home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume91 / shells / cshel500 / part03 < prev    next >
Encoding:
Internet Message Format  |  1991-03-03  |  58.6 KB

  1. Path: news.larc.nasa.gov!amiga-request
  2. From: amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
  3. Subject: v91i029: CShell 5.00 - alternative command interface, Part03/06
  4. Reply-To: <umueller@iiic.ethz.ch>
  5. Newsgroups: comp.sources.amiga
  6. Message-ID: <comp.sources.amiga:v91i029@ab20.larc.nasa.gov>
  7. References: <comp.sources.amiga:v91i027@ab20.larc.nasa.gov>
  8. Date: 03 Mar 91 21:56:06 GMT
  9. Approved: tadguy@uunet.UU.NET (Tad Guy)
  10. X-Mail-Submissions-To: amiga@uunet.uu.net
  11. X-Post-Discussions-To: comp.sys.amiga.misc
  12.  
  13. Submitted-by: <umueller@iiic.ethz.ch>
  14. Posting-number: Volume 91, Issue 029
  15. Archive-name: shells/cshell-5.00/part03
  16.  
  17. #!/bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 3 (of 6)."
  24. # Contents:  comm2.c comm3.c
  25. # Wrapped by tadguy@ab20 on Sun Mar  3 16:56:00 1991
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'comm2.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'comm2.c'\"
  29. else
  30. echo shar: Extracting \"'comm2.c'\" \(28015 characters\)
  31. sed "s/^X//" >'comm2.c' <<'END_OF_FILE'
  32. X/*
  33. X * COMM2.C
  34. X *
  35. X * (c)1986 Matthew Dillon     9 October 1986
  36. X *
  37. X * Version 2.07M by Steve Drew 10-Sep-87
  38. X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  39. X * Version 5.00L by Urban Mueller 17-Feb-91
  40. X *
  41. X */
  42. X
  43. X#include "shell.h"
  44. X
  45. X/* comm2.c */
  46. Xstatic long dptrtosecs(struct DPTR *d);
  47. Xstatic long timeof(char *s);
  48. Xstatic int evalif(void);
  49. Xstatic int clinum(char *name);
  50. Xstatic int copydir(long srcdir, long destdir, int recur);
  51. Xstatic int copyfile(char *srcname, long srcdir, char *destname, long destdir);
  52. Xstatic int file_date(struct DateStamp *date, char *name);
  53. Xstatic void changedisk(struct MsgPort *task);
  54. Xstatic int func_array(char **fav, int fac);
  55. Xstatic int func_int(int i);
  56. Xstatic int func_bool(int i);
  57. Xstatic int func_string(char *str);
  58. Xstatic int commas(char **av, int ac, int n);
  59. Xstatic int wordset(char **av, int ac, char **(*func)(char **,int,char**,int,int*,int));
  60. Xstatic int split_arg(char **av, int ac);
  61. Xstatic char *info_part(char **av, int ac, int n, char *buf);
  62. X
  63. X/* Casting conveniences */
  64. X#define BPTR_TO_C(strtag, var)  ((struct strtag *)(BADDR( (ULONG) var)))
  65. X#define PROC(task)              ((struct Process *)task)
  66. X#define CLI(proc)               (BPTR_TO_C(CommandLineInterface, proc->pr_CLI))
  67. X
  68. X/* Externs */
  69. Xextern int has_wild;                    /* flag set if any arg has a ? or * */
  70. X
  71. X/* globals */
  72. Xstatic int cp_update, cp_date, cp_flags, cp_fresh;
  73. X
  74. Xdo_abortline( void )
  75. X{
  76. X    Exec_abortline = 1;
  77. X    return 0;
  78. X}
  79. X
  80. Xdo_return( void )
  81. X{
  82. X    int retcode=(ac<2 ? 0 : atoi(av[1]));
  83. X
  84. X    Exec_abortline = 1;
  85. X    if (Src_stack) {
  86. X#ifdef AZTEC_C
  87. X        FILE *ptr = Src_base[Src_stack - 1];
  88. X        ptr->_bp = ptr->_bend;
  89. X        ptr->_flags |= _IOEOF;
  90. X#else
  91. X        fseek (Src_base[Src_stack - 1], 0L, 2);
  92. X#endif
  93. X        return retcode;
  94. X    } else
  95. X        main_exit(retcode);
  96. X    return 0;
  97. X}
  98. X
  99. X/*
  100. X * STRHEAD
  101. X *
  102. X * place a string into a variable removing everything after and including
  103. X * the 'break' character
  104. X *
  105. X * strhead varname breakchar string
  106. X *
  107. X */
  108. X
  109. Xdo_strhead( void )
  110. X{
  111. X    char *s;
  112. X    if (s=index(av[3],*av[2])) *s='\0';
  113. X    set_var (LEVEL_SET, av[1], av[3]);
  114. X    return 0;
  115. X}
  116. X
  117. Xdo_strtail( void )
  118. X{
  119. X    char *s;
  120. X    if (s=index(av[3],*av[2])) s++; else s=av[3];
  121. X    set_var (LEVEL_SET, av[1], s);
  122. X    return 0;
  123. X}
  124. X
  125. Xstatic long
  126. Xdptrtosecs(struct DPTR *d)
  127. X{
  128. X    struct DateStamp *ds=(&d->fib->fib_Date);
  129. X    return ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND;
  130. X}
  131. X
  132. Xstatic long
  133. Xtimeof(char *s)
  134. X{
  135. X    struct DPTR *d;
  136. X    int dummy;
  137. X    long n;
  138. X
  139. X    if ( (d=dopen(s,&dummy))==NULL ) return 0L;
  140. X    n=dptrtosecs(d);
  141. X    dclose(d);
  142. X    return n;
  143. X}
  144. X
  145. X/*
  146. X * if -f file (exists) or:
  147. X *
  148. X * if A < B   <, >, =, <=, >=, <>, where A and B are either:
  149. X * nothing
  150. X * a string
  151. X * a value (begins w/ number)
  152. X */
  153. X
  154. Xdo_if( char *garbage, int com )
  155. X{
  156. X    int result;
  157. X
  158. X    switch (com) {
  159. X    case 0:
  160. X        if (If_stack && If_base[If_stack - 1])
  161. X            If_base[If_stack++] = 1;
  162. X        else {
  163. X            result=evalif();
  164. X            If_base[If_stack++]=(options & 64 ? result : !result);
  165. X        }
  166. X        break;
  167. X    case 1:
  168. X        if (If_stack > 1 && If_base[If_stack - 2]) break;
  169. X        if (If_stack) If_base[If_stack - 1] ^= 1;
  170. X        break;
  171. X    case 2:
  172. X        if (If_stack) --If_stack;
  173. X        break;
  174. X    }
  175. X    disable = (If_stack) ? If_base[If_stack - 1] : 0;
  176. X    if (If_stack >= MAXIF) {
  177. X        fprintf(stderr,"If's too deep\n");
  178. X        disable = If_stack = 0;
  179. X        return -1;
  180. X    }
  181. X    if (forward_goto) disable = If_base[If_stack - 1] = 0;
  182. X    return 0;
  183. X}
  184. X
  185. Xstatic int
  186. Xevalif(void)
  187. X{
  188. X    char c, *str, *left, *right, *cmp;
  189. X    long num, t0, isint, i=1;
  190. X
  191. X    switch(options & ~64) {
  192. X    case 0:
  193. X        for( i=1; i<ac; i++ )
  194. X            if( strlen(str=av[i])<=2 && *str && index("<=>",*str) &&
  195. X                   (!str[1] || index("<=>",str[1])))
  196. X                break;
  197. X
  198. X        if ( i==ac )
  199. X            return ac>1 && *av[1] && strcmp(av[1],"0");
  200. X
  201. X        left = compile_av(av,1,i   ,0xA0, 0);
  202. X        right= compile_av(av,i+1,ac,0xA0, 0);
  203. X        cmp  = av[i];
  204. X        num  = Atol(left);
  205. X        isint  = ! IoErr();
  206. X        num -= Atol(right);
  207. X        isint &= ! IoErr();
  208. X        if (!isint) num=strcmp(left,right);
  209. X        if (num < 0)       c='<';
  210. X        else if (num > 0)  c='>';
  211. X        else if (num == 0) c='=';
  212. X        return index(cmp, c) != NULL;
  213. X    case 1:
  214. X        return do_rpn(NULL,i);
  215. X    case 2:
  216. X        return exists(av[i]);
  217. X    case 4:
  218. X        t0=timeof(av[i++]);
  219. X        for ( ; i<ac ; i++)
  220. X            if (t0<=timeof(av[i])) return 1;
  221. X        return 0;
  222. X    case 8:
  223. X        return AvailMem( MEMF_FAST )!=0;
  224. X    case 16:
  225. X        return isdir(av[i])!=0;
  226. X    case 32:
  227. X        return get_var(LEVEL_SET,av[i]) != 0;
  228. X    default:
  229. X        ierror(NULL,500);
  230. X    }
  231. X    return 0;
  232. X}
  233. X
  234. Xdo_label( void )
  235. X{
  236. X    char aseek[32];
  237. X
  238. X    if (Src_stack == 0) {
  239. X        ierror (NULL, 502);
  240. X        return -1;
  241. X    }
  242. X
  243. X    sprintf (aseek, "%ld %d", Src_pos[Src_stack-1], If_stack);
  244. X    set_var (LEVEL_LABEL + Src_stack - 1, av[1], aseek);
  245. X    if (!strcmp(av[1],get_var(LEVEL_SET,v_gotofwd)))
  246. X        forward_goto = 0;
  247. X    return 0;
  248. X}
  249. X
  250. Xdo_goto( void )
  251. X{
  252. X    int new;
  253. X    long pos;
  254. X    char *lab;
  255. X
  256. X    if (Src_stack == 0) {
  257. X        ierror (NULL, 502);
  258. X    } else {
  259. X        lab = get_var (LEVEL_LABEL + Src_stack - 1, av[1]);
  260. X        if (lab == NULL) {
  261. X            forward_goto = 1;
  262. X            set_var (LEVEL_SET, v_gotofwd, av[1]);
  263. X            return(0);
  264. X        } else {
  265. X            pos = atoi(lab);
  266. X            fseek (Src_base[Src_stack - 1], pos, 0);
  267. X            Src_pos[Src_stack - 1] = pos;
  268. X            new = atoi(next_word(lab));
  269. X            for (; If_stack < new; ++If_stack)
  270. X                If_base[If_stack] = 0;
  271. X            If_stack = new;
  272. X        }
  273. X    }
  274. X    Exec_abortline = 1;
  275. X    return (0);      /* Don't execute rest of this line */
  276. X}
  277. X
  278. X
  279. Xdo_inc(char *garbage, int com)
  280. X{
  281. X    char *var, num[32];
  282. X
  283. X    if (ac>2) com *= atoi(av[2]);
  284. X    if (var = get_var (LEVEL_SET, av[1])) {
  285. X        sprintf (num, "%d", atoi(var)+com);
  286. X        set_var (LEVEL_SET, av[1], num);
  287. X    }
  288. X    return 0;
  289. X}
  290. X
  291. Xdo_input( void )
  292. X{
  293. X    char *str, in[256], *get, *put;
  294. X    int i, quote=0;
  295. X
  296. X    if( options&2 ) {
  297. X        if( !IsInteractive(Input()) ) return 20;
  298. X        setrawcon( -1, 0 );
  299. X        in[1]=0;
  300. X        for ( i=1; i<ac; ++i) {
  301. X            in[0]=getchar();
  302. X            set_var (LEVEL_SET, av[i], in);
  303. X        }
  304. X        setrawcon( 2, 0 );
  305. X        return 0;
  306. X    }
  307. X
  308. X    for ( i=1; i<ac; ++i)
  309. X        if (fgets(in,256,stdin)) {
  310. X            str=in, put=in+strlen(in)-1;
  311. X            if( *put=='\n' ) *put=0;
  312. X            if( !(options&1) ) {
  313. X                while( *str==' ' ) str++;
  314. X                for( put=get=str; *get; get++) {
  315. X                    if( *get=='\"' )
  316. X                        quote=1-quote;
  317. X                    else if( *get==' ' && !quote )
  318. X                        *put++=0xA0;
  319. X                    else 
  320. X                        *put++=*get;
  321. X                }
  322. X                *put=0;
  323. X                while( put>str && *(put-1)==0xA0 ) *--put=0;
  324. X            }
  325. X            set_var (LEVEL_SET, av[i], str);
  326. X        }
  327. X    return 0;
  328. X}
  329. X
  330. Xdo_ver( void )
  331. X{
  332. X    extern char shellname[];
  333. X
  334. X    puts(shellname);
  335. X    puts("1.00 Lattice (c) 1986 Matthew Dillon\n"
  336. X         "2.05 Manx (M) versions by Steve Drew\n"
  337. X         "3.02 ARP (A) versions by Carlo Borreo, Cesare Dieni\n"
  338. X         "4.00 ARP 1.3 version by Carlo Borreo, Cesare Dieni\n"
  339. X         "5.00 Lattice version by Urban Mueller (umueller@iiic.ethz.ch)\n");
  340. X    printf("Compiled: "__DATE__" "__TIME__" with "COMPILER"\n" );
  341. X    return 0;
  342. X}
  343. X
  344. X
  345. Xstatic int
  346. Xclinum( char *name )
  347. X{
  348. X    int ncli=(long)FindCLI(0L), count;
  349. X    struct Task *task;
  350. X    char cmd[40+1];
  351. X
  352. X    if( *name>='0' && *name<='9' )
  353. X        return atoi( name );
  354. X
  355. X    Forbid();
  356. X    for (count = 1; count <= ncli ; count++)
  357. X        if (task = (struct Task *)FindCLI(count)) {
  358. X            if ( !PROC(task)->pr_TaskNum || PROC(task)->pr_CLI == 0) continue;
  359. X            BtoCStr(cmd,   CLI(PROC(task))->cli_CommandName, 40L);
  360. X            if( !Strcmp( BaseName( cmd ), name ))
  361. X                goto done;
  362. X        }
  363. X    count=-1;
  364. Xdone:
  365. X    Permit();
  366. X    return count;
  367. X}
  368. X
  369. Xdo_ps( void )
  370. X{
  371. X    /* this code fragment based on ps.c command by Dewi Williams */
  372. X    int count;             /* loop variable         */
  373. X    struct Task *task;     /* EXEC descriptor       */
  374. X    char strbuf[64+1];     /* scratch for btocstr() */
  375. X    char cmd[40+1], *com;  /* holds cmd name        */
  376. X    long ncli,mycli,cli,i;
  377. X
  378. X    char onoff[80];
  379. X    memset( onoff, 0, 80 );
  380. X    for( i=1; i<ac; i++ )
  381. X        onoff[ 1+clinum( av[i] ) ]=1;
  382. X    if( options&2 )
  383. X        for( i=0; i<80; i++ )
  384. X            onoff[i]=1-onoff[i];
  385. X
  386. X    printf("Proc Command Name         CLI Type    Pri.  Address  Directory\n");
  387. X    Forbid();
  388. X
  389. X    ncli=(long)FindCLI(0L);
  390. X    mycli=interactive() ? Myprocess->pr_TaskNum : -1;
  391. X    for (count = 1; count <= ncli ; count++)             /* or just assume 20?*/
  392. X        if (task = (struct Task *)FindCLI((long)count)) {/* Sanity check      */
  393. X            cli=PROC(task)->pr_TaskNum;
  394. X            if( ac>1 && !onoff[1+cli] )
  395. X                continue;
  396. X            if ( cli==0 || PROC(task)->pr_CLI == 0) continue; /* or complain? */
  397. X                BtoCStr(cmd,   CLI(PROC(task))->cli_CommandName, 40L);
  398. X                BtoCStr(strbuf,CLI(PROC(task))->cli_SetName    , 64L);
  399. X            com=cmd;
  400. X            if( !(options&1) )
  401. X                com=BaseName(com);
  402. X            printf("%c%2d  %-20.20s %-11.11s %3d  %8lx  %s\n",
  403. X                cli==mycli ? '*' : ' ',
  404. X                count,
  405. X                com,
  406. X                task->tc_Node.ln_Name,
  407. X                (signed char)task->tc_Node.ln_Pri,
  408. X                task,
  409. X                strbuf
  410. X            );
  411. X        }
  412. X
  413. X    Permit();
  414. X    return 0;
  415. X}
  416. X
  417. X/*
  418. X * CP [-d] [-u] file file
  419. X * CP [-d] [-u] file file file... destdir
  420. X * CP [-r][-u][-d] dir dir dir... destdir
  421. X */
  422. X
  423. Xchar *errstr;          /* let's be alittle more informative */
  424. X
  425. Xdo_copy( void )
  426. X{
  427. X    int recur, ierr;
  428. X    char *destname;
  429. X    char destisdir;
  430. X    FIB *fib;
  431. X    int i=1;
  432. X
  433. X    errstr = "";
  434. X    ierr = 0;
  435. X
  436. X    fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  437. X
  438. X    recur     = (options & 0x01);
  439. X    cp_update = (options & 0x02);
  440. X    cp_date   =!(options & 0x04); /* the default is keep orignal file date */
  441. X    cp_flags  =!(options & 0x08);
  442. X    cp_fresh  = (options & 0x10);
  443. X
  444. X    destname = av[ac - 1];
  445. X
  446. X    if (ac < i + 2) {
  447. X        ierr = 500;
  448. X        goto done;
  449. X    }
  450. X    destisdir = isdir(destname);
  451. X    if (ac > i + 2 && !destisdir) {
  452. X        ierr = 507;
  453. X        goto done;
  454. X    }
  455. X
  456. X/*
  457. X * copy set:                        reduce to:
  458. X *    file to file                     file to file
  459. X *    dir  to file (NOT ALLOWED)
  460. X *    file to dir                      dir to dir
  461. X *    dir  to dir                      dir to dir
  462. X *
  463. X */
  464. X
  465. X    for (; i<ac-1 && !dobreak(); ++i) {
  466. X        short srcisdir = isdir(av[i]);
  467. X        if (srcisdir && has_wild && (ac >2)) /* hack to stop dir's from */
  468. X            continue;                    /* getting copied if specified */
  469. X                                         /* from wild expansion         */
  470. X        if (srcisdir) {
  471. X            BPTR srcdir, destdir;
  472. X            if (!destisdir) {
  473. X                if (exists(destname)) {
  474. X                    ierr = 507;    /* disallow dir to file */
  475. X                    goto done;
  476. X                    }
  477. X                if (destdir = CreateDir(destname)) UnLock(destdir);
  478. X                destisdir = 1;
  479. X            }
  480. X            if (!(destdir = Lock(destname, ACCESS_READ))) {
  481. X                ierr = 205;
  482. X                errstr = destname;
  483. X                goto done;
  484. X            }
  485. X            if (!(srcdir = Lock(av[i], ACCESS_READ))) {
  486. X                ierr = 205;
  487. X                errstr = av[i];
  488. X                UnLock(destdir);
  489. X                goto done;
  490. X            }
  491. X            ierr = copydir(srcdir, destdir, recur);
  492. X            UnLock(srcdir);
  493. X            UnLock(destdir);
  494. X            if (ierr) break;
  495. X        } else {                   /* FILE to DIR,   FILE to FILE   */
  496. X            BPTR destdir, srcdir, tmp;
  497. X            char *destfilename;
  498. X
  499. X            srcdir = (BPTR)(Myprocess->pr_CurrentDir);
  500. X
  501. X            if ((tmp = Lock(av[i], ACCESS_READ)) == NULL || !Examine(tmp,fib)) {
  502. X                if (tmp) UnLock(tmp);
  503. X                ierr = 205;
  504. X                errstr = av[i];
  505. X                goto done;
  506. X            }
  507. X            UnLock(tmp);
  508. X            if (destisdir) {
  509. X                destdir = Lock(destname, ACCESS_READ);
  510. X                destfilename = fib->fib_FileName;
  511. X            } else {
  512. X                destdir = srcdir;
  513. X                destfilename = destname;
  514. X            }
  515. X            printf(" %s..",av[i]);
  516. X            fflush(stdout);
  517. X            ierr = copyfile(av[i], srcdir, destfilename, destdir);
  518. X            if (destisdir) UnLock(destdir);
  519. X            if (ierr) break;
  520. X        }
  521. X    }
  522. X
  523. Xdone:
  524. X
  525. X    FreeMem(fib, (long)sizeof(FIB));
  526. X    if (ierr) {
  527. X        ierror(errstr, ierr);
  528. X        return(20);
  529. X    }
  530. X    return 0;
  531. X}
  532. X
  533. Xstatic int
  534. Xcopydir(BPTR srcdir, BPTR destdir, int recur)
  535. X{
  536. X    static int level;
  537. X    BPTR cwd;
  538. X    FIB *srcfib;
  539. X    BPTR destlock, srclock;
  540. X    int ierr;
  541. X
  542. X    level++;
  543. X    ierr = 0;
  544. X    srcfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  545. X    if (Examine(srcdir, srcfib)) {
  546. X        while (ExNext(srcdir, srcfib)) {
  547. X            if (CHECKBREAK())
  548. X                break;
  549. X            if (srcfib->fib_DirEntryType < 0) {
  550. X                printf("%*s%s..",(level-1) * 6," ",srcfib->fib_FileName);
  551. X                fflush(stdout);
  552. X                ierr = copyfile(srcfib->fib_FileName,srcdir,srcfib->fib_FileName,destdir);
  553. X                if (ierr) break;
  554. X            } else {
  555. X                if (recur) {
  556. X                    cwd = CurrentDir(srcdir);
  557. X                    if (srclock = Lock(srcfib->fib_FileName, ACCESS_READ)) {
  558. X                        CurrentDir(destdir);
  559. X                        if (!(destlock = Lock(srcfib->fib_FileName,ACCESS_WRITE))) {
  560. X                            destlock = CreateDir(srcfib->fib_FileName);
  561. X                            printf("%*s%s (Dir)....[Created]\n",(level-1) * 6,
  562. X                                   " ",srcfib->fib_FileName);
  563. X
  564. X                            /* UnLock and re Lock if newly created
  565. X                             * for file_date() to work properly */
  566. X                            if (destlock)
  567. X                                UnLock(destlock);
  568. X                            destlock = Lock(srcfib->fib_FileName, ACCESS_WRITE);
  569. X                        } else
  570. X                            printf("%*s%s (Dir)\n",(level-1) * 6," ",srcfib->fib_FileName);
  571. X                        if (destlock) {
  572. X                            ierr = copydir(srclock, destlock, recur);
  573. X                            UnLock(destlock);
  574. X                        } else {
  575. X                            ierr = (int)((long)IoErr());
  576. X                        }
  577. X                        UnLock(srclock);
  578. X                    } else {
  579. X                        ierr = (int)((long)IoErr());
  580. X                    }
  581. X                    CurrentDir(cwd);
  582. X                    if (ierr)
  583. X                        break;
  584. X                }
  585. X            }
  586. X        }
  587. X    } else {
  588. X        ierr = IoErr();
  589. X    }
  590. X    --level;
  591. X    FreeMem(srcfib, (long)sizeof(FIB));
  592. X    return(ierr);
  593. X}
  594. X
  595. X#define COPYBUF 8192
  596. X
  597. Xstatic int
  598. Xcopyfile(char *srcname, BPTR srcdir, char *destname, BPTR destdir)
  599. X{
  600. X    BPTR cwd;
  601. X    BPTR f1, f2;
  602. X    long i;
  603. X    int stat,ierr;
  604. X    char *buf;
  605. X    struct DPTR *dp, *dps = NULL;
  606. X
  607. X    if ((buf = (char *)AllocMem(COPYBUF, MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  608. X        { ierr = 103; goto fail; }
  609. X    ierr = 0;
  610. X    cwd = CurrentDir(srcdir);
  611. X    if ((f1=Open(srcname, MODE_OLDFILE))==NULL)
  612. X        { errstr = srcname; ierr = 205; goto fail; }
  613. X    dps = dopen(srcname,&stat);
  614. X    CurrentDir(destdir);
  615. X    if (cp_update || cp_fresh) {
  616. X        if( dp=dopen(destname, &stat) ) {
  617. X            if ( dptrtosecs(dp) >= dptrtosecs(dps) &&
  618. X                      !Strcmp(dps->fib->fib_FileName, dp->fib->fib_FileName))
  619. X            { dclose(dp); Close(f1); printf("..not newer\n"); goto fail; }
  620. X            dclose(dp);
  621. X        } else if( cp_fresh ) {
  622. X            Close(f1); printf("..not there\n"); goto fail;
  623. X        }
  624. X    }
  625. X    if ((f2=Open(destname, MODE_NEWFILE))==NULL)
  626. X        { Close(f1); ierr = (int)((long)IoErr()); errstr=destname; goto fail;  }
  627. X    while (i = Read(f1, buf, COPYBUF))
  628. X        if (Write(f2, buf, i) != i)
  629. X            { ierr = IoErr(); break; }
  630. X    Close(f2);
  631. X    Close(f1);
  632. X    if (!ierr) {
  633. X        if (cp_date) file_date(&dps->fib->fib_Date, destname);
  634. X        if (cp_flags ) {
  635. X            SetProtection( destname, dps->fib->fib_Protection&~FIBF_ARCHIVE);
  636. X            if( *dps->fib->fib_Comment )
  637. X                SetComment( destname, dps->fib->fib_Comment );
  638. X        }
  639. X        printf("..copied\n");
  640. X    } else
  641. X        DeleteFile(destname);
  642. Xfail:
  643. X    dclose(dps);
  644. X    if (buf) FreeMem(buf, 8192L);
  645. X    CurrentDir(cwd);
  646. X    return(ierr);
  647. X}
  648. X
  649. Xdo_touch( void )
  650. X{
  651. X    struct DateStamp ds;
  652. X    int i;
  653. X    DateStamp(&ds);
  654. X    for (i=1; i<ac; i++)
  655. X        if (file_date(&ds, av[i]))
  656. X            ierror(av[i],500);
  657. X        else 
  658. X            clear_archive_bit( av[i] );
  659. X    return 0;
  660. X}
  661. X
  662. Xstatic int
  663. Xfile_date( struct DateStamp *date, char *name )
  664. X{
  665. X    long packargs[7];
  666. X    struct MsgPort *task;
  667. X    struct DPTR *tmp;
  668. X    BPTR dirlock;
  669. X    char *ptr;
  670. X    int stat;
  671. X
  672. X    if (!(task = (struct MsgPort *)DeviceProc(name))) return(1);
  673. X    if (tmp = dopen(name, &stat)) {
  674. X        dirlock = ParentDir(tmp->lock);
  675. X        ptr=AllocMem(65L,MEMF_PUBLIC);
  676. X        CtoBStr(tmp->fib->fib_FileName,(ULONG)ptr >> 2L,64L);
  677. X        dclose(tmp);
  678. X        packargs[1]=dirlock;
  679. X        packargs[2]=(ULONG)ptr >> 2L;
  680. X        packargs[3]=(long)date;
  681. X        SendPacket(ACTION_SET_DATE,packargs,task);
  682. X        UnLock(dirlock);
  683. X        FreeMem(ptr,65L);
  684. X    }
  685. X    return 0;
  686. X}
  687. X
  688. Xdo_addbuffers( void )
  689. X{
  690. X    long packargs[7], i;
  691. X    struct MsgPort *task;
  692. X
  693. X    for( i=1; i<=ac-2; i+=2 ) {
  694. X        if( i==ac-1 )
  695. X            { ierror( av[i], 500 ); return 20; }
  696. X        if( !(task=(struct MsgPort *)DeviceProc(av[i])))
  697. X            { ierror(av[1],510); return 20; }
  698. X        packargs[0]=myatoi(av[i+1],1,32767); if (atoierr) return 20;
  699. X        SendPacket(ACTION_MORE_CACHE,packargs,task);
  700. X    }
  701. X    return 0;
  702. X}
  703. X
  704. Xdo_relabel( void )
  705. X{
  706. X    long packargs[7];
  707. X    struct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
  708. X    char *ptr;
  709. X
  710. X    if (!task) { ierror(av[1],510); return 20; }
  711. X    ptr=AllocMem(65L,MEMF_PUBLIC);
  712. X    CtoBStr(av[2],(ULONG)ptr >> 2L,64L);
  713. X    packargs[0]=(ULONG)ptr >> 2L;
  714. X    SendPacket(ACTION_RENAME_DISK,packargs,task);
  715. X    FreeMem(ptr,65L);
  716. X    Delay(10);
  717. X    changedisk(task);
  718. X    return 0;
  719. X}
  720. X
  721. Xdo_diskchange( void )
  722. X{
  723. X    struct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
  724. X
  725. X    if (!task) { ierror(av[1],510); return 20; }
  726. X    changedisk(task);
  727. X    return 0;
  728. X}
  729. X
  730. Xstatic void
  731. Xchangedisk(struct MsgPort *task)
  732. X{
  733. X    long packargs[7];
  734. X
  735. X    packargs[0]=1L;
  736. X    SendPacket(ACTION_INHIBIT,packargs,task);
  737. X    packargs[0]=0L;
  738. X    SendPacket(ACTION_INHIBIT,packargs,task);
  739. X}
  740. X
  741. X
  742. Xextern int atoierr;
  743. X
  744. Xstatic int
  745. Xfunc_array( char *fav[], int fac)
  746. X{
  747. X    char *ret;
  748. X    if( atoierr ) return 20;
  749. X    if( fac ) {
  750. X        ret=compile_av( fav, 0, fac, 0xa0, 0);
  751. X        set_var( LEVEL_SET, v_value, ret );
  752. X        free( ret );
  753. X    } else 
  754. X        unset_var( LEVEL_SET, v_value );
  755. X    return 0;
  756. X}
  757. X
  758. Xstatic int
  759. Xfunc_int( int i )
  760. X{
  761. X    char buf[12];
  762. X    if( atoierr ) return 20;
  763. X    sprintf(buf,"%d",i);
  764. X    set_var( LEVEL_SET, v_value, buf );
  765. X    return 0;
  766. X}
  767. X
  768. Xstatic int
  769. Xfunc_bool( int i )
  770. X{
  771. X    if( atoierr ) return 20;
  772. X    set_var( LEVEL_SET, v_value, i ? "1" : "0" );
  773. X    return 0;
  774. X}
  775. X
  776. Xstatic int
  777. Xfunc_string( char *str )
  778. X{
  779. X    if( atoierr ) return 20;
  780. X    set_var( LEVEL_SET, v_value, str ? str : "" );
  781. X    return 0;
  782. X}
  783. X
  784. Xstatic int
  785. Xcommas( char *av[], int ac, int n )
  786. X{
  787. X    int i=0;
  788. X
  789. X    while( --ac>=0 )
  790. X        if( !strcmp( *av++, ",") )
  791. X            i++;
  792. X    if( i-=n )
  793. X        fprintf( stderr, "Need %d comma%s\n", n, (n==1) ? "" : "s" );
  794. X    return i;
  795. X}
  796. X
  797. Xextern char **without(), **and(), **or();
  798. X
  799. Xstatic int
  800. Xwordset( char *av[], int ac, char **(*func)(char **,int,char**,int,int*,int) )
  801. X{
  802. X    char **av1=av, **av2;
  803. X    int  ac1=0, ac2, ret;
  804. X
  805. X    if( commas( av, ac, 1 ) ) return 20;
  806. X    while( strcmp( *av++, ",") ) ac1++;
  807. X    av2=av, ac2=ac-ac1-1;
  808. X    av=(*func)( av1, ac1, av2, ac2, &ac, 0 );
  809. X    ret=func_array( av, ac );
  810. X    free( av );
  811. X    return ret;
  812. X}
  813. X
  814. Xstatic int
  815. Xsplit_arg( char **av, int ac )
  816. X{
  817. X    char **arr, **old, *arg;
  818. X    int i, j=1, ret;
  819. X
  820. X    for( i=strlen(av[0])-1; i>=0; i-- )
  821. X        if( av[0][i]==' ' )
  822. X            av[0][i]=0, j++;
  823. X
  824. X    arr=old=(char **)malloc( j*sizeof( char * ) );
  825. X    arg=*av;
  826. X    for( ; j>0; j-- ) {
  827. X        *arr++=arg;
  828. X        arg+=strlen(arg)+1;
  829. X    }
  830. X    ret=func_array( old, arr-old );
  831. X    free(old);
  832. X    return ret;
  833. X}
  834. X
  835. Xstatic char *
  836. Xinfo_part( char **av, int ac, int n, char *buf )
  837. X{
  838. X    char *str;
  839. X    struct DPTR *dp;
  840. X    int len=0, i, t;
  841. X
  842. X    buf[0]=0;
  843. X    while( --ac>=0 ) {
  844. X        if( dp=dopen( av[0], &t) ) {
  845. X            if( n==0 ) {
  846. X                for (str=buf, i=7; i>=0; i--)
  847. X                    *str++= (dp->fib->fib_Protection & (1L<<i) ?
  848. X                            "hspa----" : "----rwed")[7-i];
  849. X                *str=0;
  850. X            } else len+= dp->fib->fib_NumBlocks+1;
  851. X            dclose( dp );
  852. X        }
  853. X    }
  854. X    if( n ) sprintf(buf, "%d", len);
  855. X    return buf;
  856. X}
  857. X
  858. Xstatic struct FileRequester freq;
  859. X
  860. Xstatic char *
  861. Xfile_request(char **av, int ac, char *path)
  862. X{
  863. X    struct FileRequester fr;
  864. X    char filebuf[128];
  865. X
  866. X    path[0]=0; filebuf[0]=0;
  867. X    fr=freq; /* clear everything */
  868. X    fr.fr_Hail="";
  869. X    if( ac>0 ) {
  870. X        fr.fr_Hail=av[0];
  871. X        if( ac>1 ) {
  872. X            strcpy( path,av[1]);
  873. X            if( ac>2 )
  874. X                strcpy(filebuf,av[2]);
  875. X        }
  876. X    }
  877. X    fr.fr_File  = filebuf;
  878. X    fr.fr_Dir   = path;
  879. X    fr.fr_Flags2= FR2F_LongPath;
  880. X    if( !FileRequest( &fr ) )
  881. X        return NULL;
  882. X    TackOn( path,filebuf );
  883. X    return path;
  884. X}
  885. X
  886. Xint
  887. Xconfirm( char *title, char *file )
  888. X{
  889. X    char buf[80];
  890. X
  891. X    buf[0]=0;
  892. X
  893. X    if( !confirmed ) {
  894. X        fprintf(stderr,"%s %s%-16s%s [YES/no/all/done] ? ",
  895. X                        title,o_hilite,file,o_lolite);
  896. X        strupr(fgets(buf,80,stdin));
  897. X        if( *buf=='A' )
  898. X            confirmed=1;
  899. X        if( *buf=='D' || breakcheck() )
  900. X            confirmed=2;
  901. X    }
  902. X
  903. X    if( confirmed==2 )
  904. X        return 0;
  905. X    return confirmed || *buf != 'N';
  906. X}
  907. X
  908. Xenum funcid {
  909. X    FN_STUB=1, FN_MEMBER, FN_DIRS, FN_NAMEEXT, FN_NAMEROOT, FN_FILES,
  910. X    FN_FILELEN, FN_SORTARGS, FN_UPPER, FN_WORDS, FN_ABBREV, FN_ABS,
  911. X    FN_BINTODEC, FN_CENTER, FN_COMPARE, FN_DECTOHEX, FN_DELWORD,
  912. X    FN_DELWORDS, FN_EXISTS, FN_INDEX, FN_STRCMP, FN_SUBWORDS,
  913. X    FN_WORD, FN_MIN, FN_MAX, FN_DRIVES, FN_WITHOUT, FN_UNION, FN_INTERSECT,
  914. X    FN_AVAILMEM, FN_UNIQUE, FN_RPN, FN_CONCAT, FN_SPLIT, FN_DRIVE,
  915. X    FN_FILEPROT, FN_FILEBLKS, FN_LOWER, FN_HOWMANY, FN_COMPLETE, FN_FIRST,
  916. X    FN_LAST, FN_MATCH, FN_CLINUM, FN_FREEBYTES, FN_FREEBLKS, FN_INFO,
  917. X    FN_MEGS, FN_FREESTORE, FN_CHECKPORT, FN_PICKOPTS, FN_PICKARGS,
  918. X    FN_FILEREQ, FN_VOLUME, FN_LOOKFOR, FN_APPSUFF, FN_PATHNAME, FN_AGE,
  919. X    FN_GETCLASS, FN_CONFIRM, FN_WINWIDTH, FN_WINHEIGHT, FN_WINTOP,
  920. X    FN_WINLEFT
  921. X};
  922. X
  923. Xstruct FUNCTION {
  924. X    short id, minargs, maxargs;
  925. X    char *name;
  926. X} Function[]={
  927. XFN_ABBREV,   2, 3,     "abbrev",
  928. XFN_ABS,      1, 1,     "abs",
  929. XFN_AGE,      1, 1,     "age",
  930. XFN_APPSUFF,  2, 2,     "appsuff",
  931. XFN_AVAILMEM, 0, 1,     "availmem",
  932. XFN_STUB,     1, 1,     "basename",
  933. XFN_CENTER,   2, 2,     "center",
  934. XFN_CHECKPORT,1, 1,     "checkport",
  935. XFN_CLINUM,   1, 1,     "clinum",
  936. XFN_COMPLETE, 1, MAXAV, "complete",
  937. XFN_CONCAT,   0, MAXAV, "concat",
  938. XFN_CONFIRM,  1, MAXAV, "confirm",
  939. XFN_DECTOHEX, 1, 1,     "dectohex",
  940. XFN_DELWORD,  1, MAXAV, "delword",
  941. XFN_DELWORDS, 2, MAXAV, "delwords",
  942. XFN_DIRS,     0, MAXAV, "dirs",
  943. XFN_DRIVE,    1, 1,     "drive",
  944. XFN_DRIVES,   0, 0,     "drives",
  945. XFN_EXISTS,   1, 1,     "exists",
  946. XFN_FILEBLKS, 1, MAXAV, "fileblks",
  947. XFN_FILELEN,  0, MAXAV, "filelen",
  948. XFN_FILEPROT, 1, 1,     "fileprot",
  949. XFN_FILEREQ,  0, 3,     "filereq",
  950. XFN_FILES,    0, MAXAV, "files",
  951. XFN_FREEBLKS, 1, 1,     "freeblks",
  952. XFN_FREEBYTES,1, 1,     "freebytes",
  953. XFN_FREESTORE,1, 1,     "freestore",
  954. XFN_FIRST,    0, MAXAV, "first",
  955. XFN_STUB,     1, 1,     "getenv",
  956. XFN_GETCLASS, 1, 1,     "getclass",
  957. XFN_HOWMANY,  0, 0,     "howmany",
  958. XFN_INDEX,    2, 2,     "index",
  959. XFN_INFO,     1, 1,     "info",
  960. XFN_INTERSECT,1, MAXAV, "intersect",
  961. XFN_LAST,     0, MAXAV, "last",
  962. XFN_LOOKFOR,  2, 2,     "lookfor",
  963. XFN_LOWER,    0, MAXAV, "lower",
  964. XFN_MATCH,    1, MAXAV, "match",
  965. XFN_MAX,      1, MAXAV, "max",
  966. XFN_MEGS,     1, 1,     "megs",
  967. XFN_MEMBER,   1, MAXAV, "member",
  968. XFN_MIN,      1, MAXAV, "min",
  969. XFN_NAMEEXT,  1, 1,     "nameext",
  970. XFN_NAMEROOT, 1, 1,     "nameroot",
  971. XFN_PATHNAME, 1, 1,     "pathname",
  972. XFN_PICKARGS, 0, MAXAV, "pickargs",
  973. XFN_PICKOPTS, 0, MAXAV, "pickopts",
  974. XFN_RPN,      1, MAXAV, "rpn",
  975. XFN_SORTARGS, 0, MAXAV, "sortargs",
  976. XFN_SPLIT,    0, MAXAV, "split",
  977. XFN_STRCMP,   2, 2,     "strcmp",
  978. XFN_STUB,     2, 2,     "strhead",
  979. XFN_STUB,     2, 2,     "strleft",
  980. XFN_STUB,     2, 3,     "strmid",
  981. XFN_STUB,     2, 2,     "strright",
  982. XFN_STUB,     2, 2,     "strtail",
  983. XFN_SUBWORDS, 2, MAXAV, "subwords",
  984. XFN_STUB,     2, 2,     "tackon",
  985. XFN_UNION,    1, MAXAV, "union",
  986. XFN_UNIQUE,   0, MAXAV, "unique",
  987. XFN_UPPER,    0, MAXAV, "upper",
  988. XFN_VOLUME,   1, 1,     "volume",
  989. XFN_WINHEIGHT,0, 0,     "winheight",
  990. XFN_WINLEFT,  0, 0,     "winleft",
  991. XFN_WINTOP,   0, 0,     "wintop",
  992. XFN_WINWIDTH, 0, 0,     "winwidth",
  993. XFN_WITHOUT,  1, MAXAV, "without",
  994. XFN_WORD,     1, MAXAV, "word",
  995. XFN_WORDS,    0, MAXAV, "words",
  996. X0,           0, NULL
  997. X};
  998. X
  999. Xextern char shellctr[];
  1000. Xchar *strstr(), *rindex();
  1001. X
  1002. Xint
  1003. Xdofunc( int id, char **av, int ac)
  1004. X{
  1005. X    char **oldav=av, **get=av, buf[200], *str=buf;
  1006. X    int oldac=ac, i=0, j=0, n=0, n2=1, l;
  1007. X    buf[0]=0;
  1008. X    av[ac]=NULL;
  1009. X
  1010. X    switch( id ) {
  1011. X    case FN_ABBREV:
  1012. X        if( ac==3 ) i=posatoi(av[2] ); else i=strlen(av[0]);
  1013. X        return func_bool( !Strncmp( av[0], av[1], i ));
  1014. X    case FN_ABS:
  1015. X        i=unlatoi(av[0]);
  1016. X        return func_int( i>= 0 ? i : -i );
  1017. X    case FN_AGE: {
  1018. X        struct DateStamp ds; long time;
  1019. X        DateStamp( &ds ); if( ds.ds_Days==0 ) return 99999;
  1020. X        if( !(time=timeof(av[0]))) return 99999;
  1021. X        return func_int( (ds.ds_Days*86400+ds.ds_Minute*60-time)/86400 ); }
  1022. X    case FN_APPSUFF:
  1023. X        strcpy(buf,av[0]);
  1024. X        l=strlen(av[0])-strlen(av[1]);
  1025. X        if( l<0 || Strcmp(av[0]+l,av[1])) {
  1026. X            strcat(buf,".");
  1027. X            strcat(buf,av[1]);
  1028. X        }
  1029. X        return func_string( buf );
  1030. X    case FN_AVAILMEM:
  1031. X        if( ac==1 && !Strcmp(av[0],"chip")) n=MEMF_CHIP;
  1032. X        if( ac==1 && !Strcmp(av[0],"fast")) n=MEMF_FAST;
  1033. X        return func_int( AvailMem( n ));
  1034. X    case FN_CENTER:
  1035. X        if( (n=posatoi( av[1] )) > (l=strlen(av[0])) ) i=(n-l)/2, j=n-i-l;
  1036. X        sprintf( buf, "%*s%s%*s", i,"",av[0], j,"" );
  1037. X        return func_string( buf );
  1038. X    case FN_CHECKPORT:
  1039. X        return func_bool( (int)FindPort( av[0] ) );
  1040. X    case FN_GETCLASS:
  1041. X        if( str=getclass(av[0]) )
  1042. X            if( str=index(strncpy( buf,str,100 ),0xA0) )
  1043. X                *str=0;
  1044. X        return func_string(buf);
  1045. X    case FN_COMPLETE:
  1046. X        for( i=1, l=strlen(av[0]); i<ac; i++ )
  1047. X            if( !Strncmp( av[0], av[i], l ) )
  1048. X                { str=av[i]; break; }
  1049. X        return func_string( str );
  1050. X    case FN_CONCAT:
  1051. X        return func_string( compile_av( av, 0, ac, ' ', 1));
  1052. X    case FN_CONFIRM:
  1053. X        for( i=1, get++, confirmed=0; i<ac; i++ )
  1054. X            if( confirm( av[0], av[i]) )
  1055. X                *get++=av[i];
  1056. X        return func_array( av+1, (get-av)-1 );
  1057. X    case FN_DECTOHEX:
  1058. X        sprintf( buf, "%x", unlatoi( av[0] ));
  1059. X        return func_string( buf );
  1060. X    case FN_DELWORDS:
  1061. X        n2=posatoi( av[--ac] ); if( atoierr ) return 20;
  1062. X    case FN_DELWORD:
  1063. X        n=posatoi( av[--ac] )-1;
  1064. X        for( ; i<ac && i<n; i++ ) *av++=*get++;
  1065. X        for( ; i<ac && i<n+n2; i++ ) get++;
  1066. X        for( ; i<ac ; i++ ) *av++=*get++;
  1067. X        return func_array( oldav, av-oldav );
  1068. X    case FN_DIRS:
  1069. X        for( ; --ac>=0; get++ )
  1070. X            if( exists( *get ) && isdir( *get ) )
  1071. X                *av++=*get;
  1072. X        return func_array( oldav, av-oldav );
  1073. X    case FN_DRIVE:
  1074. X        return func_string( drive_name( av[0] ) );
  1075. X    case FN_DRIVES:
  1076. X        get_drives( buf );
  1077. X        return func_string( buf );
  1078. X    case FN_EXISTS:
  1079. X        return func_bool( exists( av[0] ));
  1080. X    case FN_FILEBLKS:
  1081. X        return func_string( info_part( av, ac, 1, buf ) );
  1082. X    case FN_FILELEN:
  1083. X        while( --ac>=0 )
  1084. X            i+=filesize( *av++ );
  1085. X        return func_int( i );
  1086. X    case FN_FILEPROT:
  1087. X        return func_string( info_part( av, ac, 0, buf ) );
  1088. X    case FN_FILEREQ:
  1089. X        return func_string( file_request( av, ac, buf ) );
  1090. X    case FN_FILES:
  1091. X        for( ; --ac>=0; get++ )
  1092. X            if( exists( *get ) && !isdir( *get ) )
  1093. X                *av++=*get;
  1094. X        return func_array( oldav, av-oldav );
  1095. X    case FN_FIRST:
  1096. X        return func_string( av[0] );
  1097. X    case FN_FREEBLKS:
  1098. X        return func_string( oneinfo( av[0], 3 ));
  1099. X    case FN_FREEBYTES:
  1100. X        return func_string( oneinfo( av[0], 2 ));
  1101. X    case FN_FREESTORE:
  1102. X        return func_string( oneinfo( av[0], 4 ));
  1103. X    case FN_HOWMANY:
  1104. X        Getenv( shellctr, buf, 10);
  1105. X        return func_string( buf );
  1106. X    case FN_INDEX:
  1107. X        str=strstr( av[0], av[1] );
  1108. X        return func_int( str ? (str-av[0])+1 : 0 );
  1109. X    case FN_INFO:
  1110. X        return func_string( oneinfo( av[0], 1 ));
  1111. X    case FN_INTERSECT:
  1112. X        return wordset( av, ac, and );
  1113. X    case FN_LAST:
  1114. X        return func_string( ac ? av[ac-1] : "" );
  1115. X    case FN_LOOKFOR:
  1116. X        return func_string( dofind( av[0], "", buf, av[1]));
  1117. X    case FN_LOWER:
  1118. X        while( --ac>=0 ) strlwr( *av++ );
  1119. X        return func_array( oldav, av-oldav );
  1120. X    case FN_MATCH:
  1121. X        for( str=av[--ac]; --ac>=0; get++ )
  1122. X            if( compare_ok( str, *get, 0 ) )
  1123. X                *av++=*get;
  1124. X        return func_array( oldav, av-oldav );
  1125. X    case FN_MAX:
  1126. X        for( n=MININT; i<ac; i++ ) 
  1127. X            { if( (j=unlatoi(av[i] )) > n ) n=j; if( atoierr ) return 20; }
  1128. X        return func_int( n );
  1129. X    case FN_MEGS:
  1130. X        return func_string( itok( atoi( av[0] )));
  1131. X    case FN_MEMBER:
  1132. X        for( i=1; i<ac && Strcmp(av[0],av[i]) ; i++ ) ;
  1133. X        return func_bool( ac!=i );
  1134. X    case FN_MIN:
  1135. X        for( n=MAXINT; i<ac; i++ )
  1136. X            { if( (j=unlatoi(av[i] )) < n ) n=j; if( atoierr ) return 20; }
  1137. X        return func_int( n );
  1138. X    case FN_NAMEEXT:
  1139. X        return func_string( rindex(av[0],'.') ? rindex(av[0],'.')+1 : NULL);
  1140. X    case FN_NAMEROOT:
  1141. X        if( rindex(av[0],'.') ) *rindex(av[0],'.')=0;
  1142. X        return func_string( av[0] );
  1143. X    case FN_PATHNAME:
  1144. X        str=av[0]+strlen(av[0])-1;
  1145. X        while( str>av[0] && *str!=':' && *str!='/' ) str--;
  1146. X        if( *str==':' ) str++;
  1147. X        *str=0;
  1148. X        return func_string(av[0]);
  1149. X    case FN_PICKARGS:
  1150. X        for( ; *get ; get++ )
  1151. X            if( **get!='-' )
  1152. X                *av++=*get;
  1153. X        return func_array( oldav, av-oldav );
  1154. X    case FN_PICKOPTS:
  1155. X        for( ; *get ; get++ )
  1156. X            if( **get=='-' )
  1157. X                *av++=*get;
  1158. X        return func_array( oldav, av-oldav );
  1159. X    case FN_CLINUM:
  1160. X        return func_int( clinum( av[0] ) );
  1161. X    case FN_RPN:
  1162. X        return func_int( eval_rpn( av, ac, 1 ));
  1163. X    case FN_SORTARGS:
  1164. X        QuickSort( av, ac );
  1165. X        return func_array( av, ac );
  1166. X    case FN_SPLIT:
  1167. X        return split_arg( av, ac );
  1168. X    case FN_STRCMP:
  1169. X        return func_int( strcmp( av[0], av[1] ) );
  1170. X    case FN_UNION:
  1171. X        return wordset( av, ac, or );
  1172. X    case FN_UNIQUE:
  1173. X        QuickSort( av, ac );
  1174. X        while( *get )
  1175. X            { *av++=*get++; while( *get && !Strcmp(*get,*(get-1)))
  1176. X                get++; }
  1177. X        return func_array( oldav, av-oldav );
  1178. X    case FN_UPPER:
  1179. X        while( --ac>=0 ) strupr( *av++ );
  1180. X        return func_array( oldav, oldac );
  1181. X    case FN_VOLUME:
  1182. X        return func_string( oneinfo( av[0], 5 ));
  1183. X    case FN_WINTOP:
  1184. X        return func_int( Win ? Win->TopEdge : 0 );
  1185. X    case FN_WINLEFT:
  1186. X        return func_int( Win ? Win->LeftEdge: 0 );
  1187. X    case FN_WINHEIGHT:
  1188. X        return func_int( Win ? Win->Height : 0 );
  1189. X    case FN_WINWIDTH:
  1190. X        return func_int( Win ? Win->Width  : 0 );
  1191. X    case FN_WORD:
  1192. X        n2=1; goto wordf;
  1193. X    case FN_SUBWORDS:
  1194. X        n2=posatoi( av[--ac] ); if( atoierr ) return 20;
  1195. X    wordf:
  1196. X        n=posatoi( av[--ac] )-1; if( atoierr ) return 20;
  1197. X        for( i=0; i<ac && i<n; i++ ) get++;
  1198. X        for(    ; i<ac && i<n+n2; i++ ) *av++=*get++;;
  1199. X        return func_array( oldav, av-oldav );
  1200. X    case FN_WITHOUT:
  1201. X        return wordset( av, ac, without );
  1202. X    case FN_WORDS:
  1203. X        return func_int( ac );
  1204. X    }
  1205. X    return func_string( "" );
  1206. X}
  1207. END_OF_FILE
  1208. if test 28015 -ne `wc -c <'comm2.c'`; then
  1209.     echo shar: \"'comm2.c'\" unpacked with wrong size!
  1210. fi
  1211. # end of 'comm2.c'
  1212. fi
  1213. if test -f 'comm3.c' -a "${1}" != "-c" ; then 
  1214.   echo shar: Will not clobber existing file \"'comm3.c'\"
  1215. else
  1216. echo shar: Extracting \"'comm3.c'\" \(26877 characters\)
  1217. sed "s/^X//" >'comm3.c' <<'END_OF_FILE'
  1218. X/*
  1219. X * COMM3.C
  1220. X *
  1221. X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  1222. X * Version 5.00L by Urban Mueller 17-Feb-91
  1223. X *
  1224. X */
  1225. X
  1226. X#include "shell.h"
  1227. X
  1228. X/* comm3.c */
  1229. Xstatic void doassign(char *log, char *phy);
  1230. Xstatic void assignlist(void);
  1231. Xstatic int strings_in_file(char *s);
  1232. Xstatic int htype_a_file(char *s);
  1233. Xstatic void install_menu(char **mav, int mac);
  1234. Xstatic int line_filter( char *(*line)(char *) );
  1235. X
  1236. Xstatic int
  1237. Xmyfgets( char *buf, FILE *in )
  1238. X{
  1239. X    int l;
  1240. X    char *ret;
  1241. X    if( ret=fgets(buf,253,in) ) {
  1242. X        l=strlen(buf);
  1243. X        if( buf[l-1]!='\n' )
  1244. X            buf[l]='\n', buf[l+1]=0;
  1245. X    }
  1246. X    return ret!=NULL && !dobreak();
  1247. X}
  1248. X
  1249. Xdo_tee( void )
  1250. X{
  1251. X    char buf[256];
  1252. X    FILE *out;
  1253. X
  1254. X    prepscroll( ac==1 );
  1255. X    if( ac>2 ) { ierror( av[2], 500 ); return 20; }
  1256. X    if( ac==1 ) out=stderr;
  1257. X    else if( !(out=fopen( av[1], "w" ))) { pError( av[1] ); return 20; }
  1258. X    while (myfgets(buf,stdin)) {
  1259. X        fputs(buf, stdout);
  1260. X        quickscroll();
  1261. X        fprintf(out, "%s", buf);
  1262. X    }
  1263. X    if( ac!=1 ) fclose( out );
  1264. X    return 0;
  1265. X}
  1266. X
  1267. Xdo_head( char *garbage, int com )
  1268. X{
  1269. X    int i, n;
  1270. X    FILE *f;
  1271. X    char buf[256];
  1272. X
  1273. X    if (ac>2) {
  1274. X        n=(int)(long)Atol(av[2]);
  1275. X        if (IoErr()) {
  1276. X            ierror(av[2],511);
  1277. X            return 20;
  1278. X        }
  1279. X    } else n=10;
  1280. X
  1281. X    f=fopen(av[1], "r");
  1282. X    if (f==NULL) {
  1283. X        pError(av[1]);
  1284. X        return 20;
  1285. X    }
  1286. X    if (com) {    /* tail specific part */
  1287. X        i=0;
  1288. X        while (fgets(buf, 256, f) && ! dobreak()) i++;
  1289. X        rewind(f);
  1290. X        if (n>i) n=i;
  1291. X        i=i-n;
  1292. X        while (i-- && fgets(buf, 256, f) && ! dobreak()) ;
  1293. X    }
  1294. X    for (i=1; i<=n && fgets(buf, 256, f) && ! dobreak(); i++)
  1295. X        printf("%s", buf);
  1296. X    fclose(f);
  1297. X    return 0;
  1298. X}
  1299. X
  1300. Xstatic int
  1301. Xexword( char **src, char *buf )
  1302. X{
  1303. X    *buf=0;
  1304. X    if( **src==0 ) return 0;
  1305. X    while( **src && **src!=',' )
  1306. X        *buf++=*(*src)++;
  1307. X    *buf=0; (*src)++;
  1308. X    return 1;
  1309. X}
  1310. X
  1311. Xstatic char helpfound=0;
  1312. X
  1313. Xvoid
  1314. Xman( FILE *f, char *s)
  1315. X{
  1316. X    char buf[140], entry[100];
  1317. X    int len=sprintf(entry, "    %s", s);
  1318. X
  1319. X    prepscroll(0);
  1320. X    rewind(f);
  1321. X    do                                  /* look for required argument */
  1322. X        if (fgets(buf, 140, f) == NULL)
  1323. X            return;
  1324. X    while ( Strncmp(entry, buf, len) );
  1325. X    helpfound=1;
  1326. X    do {                                /* display help */
  1327. X        quickscroll();
  1328. X        printf("%s", buf);
  1329. X        if (fgets(buf, 140, f) == NULL) return;
  1330. X    } while ( ( !isalphanum(*buf) ) && strncmp(buf, "    ", 4) && !dobreak() );
  1331. X}
  1332. X
  1333. X
  1334. Xdo_man( void )
  1335. X{
  1336. X    FILE *f;
  1337. X    int i;
  1338. X    char buf[200], name[60], *src, *var;
  1339. X
  1340. X    buf[0]=0;
  1341. X    if( var=get_var(LEVEL_SET,"_man" ) )
  1342. X        strcpy(buf,var);
  1343. X
  1344. X    if (ac==1) ac=2, av[1]="MAN";
  1345. X    for (i=1; i<ac; i++) {
  1346. X        src=buf, helpfound=0;
  1347. X        while( exword( &src, name) )
  1348. X            if( f=fopen(name, "r") ) {
  1349. X                man(f, av[i]);
  1350. X                fclose(f);
  1351. X            }
  1352. X        if( !helpfound )
  1353. X            fprintf(stderr, "Help not found for %s\n", av[i]);
  1354. X    }
  1355. X    return 0;
  1356. X}
  1357. X
  1358. Xdo_assign( void )
  1359. X{
  1360. X    int i;
  1361. X
  1362. X    if     (  ac==1  ) assignlist();
  1363. X    else if(  ac==2  ) doassign(av[1], NULL);
  1364. X    else if( !(ac&1) ) ierror(NULL, 500);
  1365. X    else
  1366. X        for( i=1; i<ac; i+=2 )
  1367. X            doassign( av[i],av[i+1] );
  1368. X    return 0;
  1369. X}
  1370. X
  1371. Xstatic char *assign_errors[4]={
  1372. X    "",
  1373. X    "Name %s is not valid\n",
  1374. X    "Weird error\n",
  1375. X    "Can't cancel %s\n"
  1376. X    };
  1377. X
  1378. X
  1379. Xstatic void
  1380. Xdoassign(char *log, char *phy)
  1381. X{
  1382. X    int last=strlen(log) - 1;
  1383. X
  1384. X    if (log[last] != ':') fprintf(stderr, "Bad name %s\n", log);
  1385. X    else {
  1386. X        log[last] = 0;
  1387. X        if( options && phy && o_kick20 ) {
  1388. X            int succ=0;
  1389. X            if     ( options&1 ) succ=AssignLate( log,phy );
  1390. X            else if( options&2 ) succ=AssignPath( log,phy );
  1391. X            if( !succ )
  1392. X                pError( log );
  1393. X        } else 
  1394. X            fprintf(stderr,assign_errors[Assign(log, phy)],phy);
  1395. X    }
  1396. X}
  1397. X
  1398. Xstatic void
  1399. Xassignlist()
  1400. X{
  1401. X    struct DirectoryEntry *de_head=NULL, *de;
  1402. X    char buf[256];
  1403. X    BPTR lock;
  1404. X    int ctr=0;
  1405. X
  1406. X    AddDADevs(&de_head, DLF_DEVICES | DLF_VOLUMES | DLF_DIRS);
  1407. X    printf("Devices:\n");
  1408. X    for (de=de_head; de && de->de_Type==DLX_DEVICE; de=de->de_Next) {
  1409. X        printf("%-8s",de->de_Name);
  1410. X        if (ctr++ == 5) { ctr=0; printf("\n"); }
  1411. X    }
  1412. X    printf("\n\nVolumes:\n");
  1413. X    for (    ;
  1414. X        de && (de->de_Type==DLX_VOLUME || de->de_Type==DLX_UNMOUNTED);
  1415. X        de=de->de_Next
  1416. X    )
  1417. X    printf( "%-16s %s\n",
  1418. X        de->de_Name,
  1419. X        de->de_Type == DLX_VOLUME ? "[Mounted]" : ""
  1420. X    );
  1421. X    printf("\nDirectories:\n");
  1422. X    for (; de && de->de_Type==DLX_ASSIGN; de=de->de_Next) {
  1423. X        if (lock=Lock(de->de_Name, ACCESS_READ)) {
  1424. X            PathName(lock, buf, 256L);
  1425. X            UnLock(lock);
  1426. X        }
  1427. X        else
  1428. X            strcpy(buf,"Unexisting lock");
  1429. X        printf("%-20s%s\n",de->de_Name,buf);
  1430. X    }
  1431. X    FreeDAList(de_head);
  1432. X}
  1433. X
  1434. Xdo_join( void )
  1435. X{
  1436. X    BPTR sou, dest;
  1437. X    char *buffer;
  1438. X    int i;
  1439. X    long n;
  1440. X    char *namedest=av[--ac];
  1441. X
  1442. X    if (options==0 && exists(namedest)) { ierror(namedest,203); return 20; }
  1443. X    if ( (buffer=malloc(8192)) == NULL ) { ierror(NULL,103); return 20; }
  1444. X    if ( (dest=Open(namedest, MODE_NEWFILE)) == NULL )
  1445. X        { pError(namedest); goto fail1; }
  1446. X    for (i=1; i<ac; i++) {
  1447. X        if ( (sou=Open(av[i], MODE_OLDFILE)) == NULL ) pError(av[i]);
  1448. X        else
  1449. X            while( (n=Read(sou, buffer, 8192L)) > 0 )
  1450. X                if (Write(dest, buffer, n) != n)
  1451. X                    { pError(namedest); Close(sou); goto fail2; }
  1452. X        Close(sou);
  1453. X    }
  1454. Xfail2:
  1455. X    Close(dest);
  1456. Xfail1:
  1457. X    free(buffer);
  1458. X    return 0;
  1459. X}
  1460. X
  1461. X#define BUFDIM 512L
  1462. X#define MAXSTR 256
  1463. X
  1464. Xint minstr;
  1465. X
  1466. Xstatic int
  1467. Xstrings_in_file(char *s)
  1468. X{
  1469. X    char c;
  1470. X    char readbuf[BUFDIM+1], strbuf[MAXSTR+1];
  1471. X    int i, strctr=0;
  1472. X    BPTR fh;
  1473. X    int out, n;
  1474. X
  1475. X    prepscroll(0);
  1476. X    if ( fh=Open(s, MODE_OLDFILE) ) {
  1477. X        fprintf(stderr, "Strings in %s (len>=%d):\n",s,minstr);
  1478. X        while ( (n=(int)Read(fh, readbuf, BUFDIM)) > 0 && !CHECKBREAK() )
  1479. X            for (i=0; i<n; i++) {
  1480. X                c=readbuf[i];
  1481. X                if (c<0x20 || c>0x7f) {
  1482. X                    out=(strctr>=minstr);
  1483. X                    if (!out) strctr=0;
  1484. X                } else {
  1485. X                    strbuf[strctr++]=c;
  1486. X                    out=(strctr>=BUFDIM);
  1487. X                }
  1488. X                if (out) {
  1489. X                    strbuf[strctr]='\0';
  1490. X                    puts(strbuf);
  1491. X                    quickscroll();
  1492. X                    strctr=0;
  1493. X                }
  1494. X            }
  1495. X        Close(fh);
  1496. X    } else
  1497. X        pError(s);
  1498. X    return 0;
  1499. X}
  1500. X
  1501. Xdo_strings( void )
  1502. X{
  1503. X    minstr=myatoi(av[--ac],1,255);
  1504. X    all_args( strings_in_file, 0);
  1505. X    return 0;
  1506. X}
  1507. X
  1508. XBPTR myfile[MAXMYFILES];
  1509. X
  1510. Xdo_open( void )
  1511. X{
  1512. X    long mode;
  1513. X    int n;
  1514. X
  1515. X    switch (toupper(av[2][0])) {
  1516. X        case 'R': mode=MODE_OLDFILE; break;
  1517. X        case 'W': mode=MODE_NEWFILE; break;
  1518. X        default : ierror(NULL,500); return 1;
  1519. X    }
  1520. X    n=myatoi(av[3],0,MAXMYFILES-1); if (atoierr) return 20;
  1521. X    if (myfile[n]) myclose(n);
  1522. X    myfile[n]=Open(av[1],mode);
  1523. X    return myfile[n]==NULL;
  1524. X}
  1525. X
  1526. Xdo_close( void )
  1527. X{
  1528. X    int i, n;
  1529. X
  1530. X    if (ac==1)
  1531. X        for (i=1; i<MAXMYFILES; i++)
  1532. X            myclose(i);
  1533. X    for (i=1; i<ac; i++) {
  1534. X        n=myatoi(av[i],0,MAXMYFILES-1); if (atoierr) return 20;
  1535. X        myclose(n);
  1536. X    }
  1537. X    return 0;
  1538. X}
  1539. X
  1540. Xvoid
  1541. Xmyclose(int n)
  1542. X{
  1543. X    if (myfile[n]) { Close(myfile[n]); myfile[n]=NULL; }
  1544. X}
  1545. X
  1546. Xdo_fileslist( void )
  1547. X{
  1548. X    int i, flag=0;
  1549. X
  1550. X    printf("Open files:");
  1551. X    for (i=0; i<MAXMYFILES; i++)
  1552. X        if (myfile[i]) { printf(" %d",i); flag=1; }
  1553. X    if (!flag) printf(" None!");
  1554. X    printf("\n");
  1555. X    return 0;
  1556. X}
  1557. X
  1558. XBPTR
  1559. XextOpen( char *name, long mode )
  1560. X{
  1561. X    if (name[0]=='.') return myfile[atoi(name+1)];
  1562. X    return Open(name,mode);
  1563. X}
  1564. X
  1565. Xvoid
  1566. XextClose(BPTR fh)
  1567. X{
  1568. X    int i;
  1569. X
  1570. X    for (i=0; i<MAXMYFILES; i++)
  1571. X        if (myfile[i]==fh) return;
  1572. X    Close(fh);
  1573. X}
  1574. X
  1575. Xdo_basename( void )
  1576. X{
  1577. X    set_var(LEVEL_SET, av[1], BaseName(av[2]));
  1578. X    return 0;
  1579. X}
  1580. X
  1581. Xdo_tackon( void )
  1582. X{
  1583. X    char buf[256];
  1584. X
  1585. X    strcpy(buf, av[2]);
  1586. X    TackOn(buf, av[3]);
  1587. X    set_var(LEVEL_SET, av[1], buf);
  1588. X    return 0;
  1589. X}
  1590. X
  1591. Xextern char shellres[];
  1592. X
  1593. Xdo_resident( void )
  1594. X{
  1595. X    int i=1;
  1596. X    struct ResidentProgramNode *p;
  1597. X    char buf[256];
  1598. X
  1599. X    if (options==0 && ac>1) options=1;
  1600. X    switch (options) {
  1601. X    case 0:
  1602. X        ObtainSemaphore (& (ArpBase->ResPrgProtection) );
  1603. X        if (p=ArpBase->ResidentPrgList) {
  1604. X            printf("Name             Users Access\n");
  1605. X            for (; p; p=p->rpn_Next)
  1606. X                printf("%-17s%5d%6d\n",
  1607. X                    p->rpn_Name, p->rpn_Usage, p->rpn_AccessCnt);
  1608. X        } else
  1609. X            printf("No resident program(s)\n");
  1610. X        ReleaseSemaphore(& (ArpBase->ResPrgProtection) );
  1611. X        break;
  1612. X    case 1:
  1613. X        for (; i<ac; i++)
  1614. X            if (loadres(av[i]))
  1615. X                printf("OK! %s is now resident\n", BaseName(av[i]));
  1616. X            else
  1617. X                pError(av[i]);
  1618. X        break;
  1619. X    case 2:
  1620. X        for (; i<ac; i++)
  1621. X            if (RemResidentPrg(av[i])) ierror(av[i],202);
  1622. X            else printf("Removed %s\n",av[i]);
  1623. X        break;
  1624. X    case 4:
  1625. X        for (; i<ac; i++) {
  1626. X            if( !o_resident ) {
  1627. X                Setenv(shellres,"1");
  1628. X                o_resident=1;
  1629. X            }
  1630. X            sprintf(buf,"res_%s",av[i]);
  1631. X            Setenv(buf,"1");
  1632. X        }
  1633. X        break;
  1634. X    default:
  1635. X        ierror(NULL,500);
  1636. X        break;
  1637. X    }
  1638. X    return 0;
  1639. X}
  1640. X
  1641. Xint
  1642. Xloadres(char *s)
  1643. X{
  1644. X    BPTR seg;
  1645. X
  1646. X    if (seg=(BPTR)LoadPrg(s)) AddResidentPrg(seg,BaseName(s));
  1647. X    return (seg != NULL);
  1648. X}
  1649. X
  1650. Xstruct ProcessControlBlock pcb={
  1651. X    4000,        /* pcb_StackSize    */
  1652. X    0,            /* pcb_Pri            */
  1653. X    };
  1654. X/* remaining field are NULL */
  1655. X    
  1656. Xdo_truerun(char *avline, int backflag)
  1657. X{
  1658. X    char name[200], *args;
  1659. X
  1660. X    if (backflag) {
  1661. X        pcb.pcb_Control=NULL;
  1662. X        pcb.pcb_Input=pcb.pcb_Output=Open("NIL:",MODE_OLDFILE);
  1663. X    } else {
  1664. X        pcb.pcb_Control=NULL;
  1665. X        pcb.pcb_Input=pcb.pcb_Output =NULL;
  1666. X    }
  1667. X    args=next_word(next_word(avline));
  1668. X
  1669. X    if(ASyncRun(av[1],args,&pcb)<0)
  1670. X        if (dofind(av[1], "", name,v_path))
  1671. X            ASyncRun(name,args,&pcb);
  1672. X        else
  1673. X            ierror(av[1],205);
  1674. X    return 0;
  1675. X}
  1676. X
  1677. Xint
  1678. Xexists( char *name )
  1679. X{
  1680. X    BPTR lock;
  1681. X
  1682. X    if (lock=Lock(name,ACCESS_READ)) {
  1683. X        UnLock(lock);
  1684. X        return 1;
  1685. X    }
  1686. X    return 0;
  1687. X}
  1688. X
  1689. Xdo_aset( void )
  1690. X{
  1691. X    Setenv(av[1],av[2]);
  1692. X    return 0;
  1693. X}
  1694. X
  1695. X#define HTYPELINE 16L
  1696. X
  1697. Xstatic int
  1698. Xhtype_a_file( char *s )
  1699. X{
  1700. X    BPTR fh;
  1701. X    long n, filesize=0;
  1702. X    char buf[HTYPELINE+1];
  1703. X    char out[80], *put;
  1704. X    int i;
  1705. X
  1706. X    if ( (fh=Open(s,MODE_OLDFILE))==NULL ) { pError(s); return 20; }
  1707. X    prepscroll(0);
  1708. X    while ( (n=Read(fh,buf,HTYPELINE))>0 && !dobreak()) {
  1709. X        put=out;
  1710. X        put+=sprintf(put,"%06lx: ",filesize);
  1711. X        filesize+=n;
  1712. X        for (i=0; i<n; i++) {
  1713. X            put+=sprintf( put,(i&3) ? "%02x" : " %02x",buf[i]);
  1714. X            if ((buf[i]&127)<0x20) buf[i]='.';
  1715. X        }
  1716. X        for ( ; i<HTYPELINE; i++) {
  1717. X            put+=sprintf( put, (i&3) ? "  " : "   ");
  1718. X            buf[i]=' ';
  1719. X        }
  1720. X        buf[i]=0;
  1721. X        sprintf(put,"    %s",buf);
  1722. X        puts(out);
  1723. X        quickscroll();
  1724. X    }
  1725. X    Close(fh);
  1726. X    return 0;
  1727. X}
  1728. X
  1729. Xdo_htype( void )
  1730. X{
  1731. X    all_args( htype_a_file, 0);
  1732. X    return 0;
  1733. X}
  1734. X
  1735. Xdo_stack( void )
  1736. X{
  1737. X    long n;
  1738. X
  1739. X    if (ac>1) {
  1740. X        n=Atol(av[1]);
  1741. X        if (!IoErr()) Mycli->cli_DefaultStack=(long)(n >> 2L);
  1742. X    }
  1743. X    else printf("current stack size is %ld bytes\n",
  1744. X                (long)Mycli->cli_DefaultStack << 2L);
  1745. X    return 0;
  1746. X}
  1747. X
  1748. Xdo_fault( void )
  1749. X{
  1750. X    struct PERROR *p;
  1751. X    int i, n;
  1752. X
  1753. X    for (i=1; i<ac; i++) {
  1754. X        n=myatoi(av[i],0,32767);
  1755. X        if (!atoierr) {
  1756. X            for (p=Perror; p->errnum && p->errnum!=n; p++);
  1757. X            if (p->errnum)
  1758. X                printf("Fault %d: %s\n",n,p->errstr);
  1759. X            else
  1760. X                printf("Fault %d not recognized\n",n);
  1761. X        }
  1762. X    }
  1763. X    return 0;
  1764. X}
  1765. X
  1766. Xstruct rpncommand {
  1767. X    char *str;
  1768. X    int parsin, parsout;
  1769. X    };
  1770. X
  1771. Xstatic struct rpncommand rpn[]={
  1772. X    "+",    2,    1,
  1773. X    "-",    2,    1,
  1774. X    "*",    2,    1,
  1775. X    "/",    2,    1,
  1776. X    "%",    2,    1,
  1777. X    "&",    2,    1,
  1778. X    "|",    2,    1,
  1779. X    "~",    1,    1,
  1780. X    ">",    2,    1,
  1781. X    "<",    2,    1,
  1782. X    "==",    2,    1,
  1783. X    "!",    1,    1,
  1784. X    "MAX",    2,    1,
  1785. X    "MIN",    2,    1,
  1786. X    "DUP",    1,    2,
  1787. X    "DROP",    1,    0,
  1788. X    "SWAP",    2,    2,
  1789. X    "HELP",    0,    0,
  1790. X    NULL,    0,    1,    /* this looks for a number */
  1791. X};
  1792. X
  1793. Xstatic long stack[50];
  1794. Xstatic int sp;
  1795. X
  1796. X
  1797. Xeval_rpn( char **av, int ac, int flag )
  1798. X{
  1799. X    char *zero="Division by zero\n";
  1800. X    struct rpncommand *temp;
  1801. X    long n0, n1, t;
  1802. X    int j, i=0, oldsp=sp;
  1803. X
  1804. X    for (; i<ac; i++) {
  1805. X        for (j=0; rpn[j].str && Strcmp(rpn[j].str,av[i]); j++) ;
  1806. X        n0=stack[sp-1];
  1807. X        n1=stack[sp-2];
  1808. X        sp -= (rpn[j].parsin);
  1809. X        if (sp<0) { fprintf(stderr, "RPN: Empty stack\n"); goto error; }
  1810. X        switch (j) {
  1811. X          case 0:    n0 += n1;            break;
  1812. X          case 1:    n0 = n1-n0;            break;
  1813. X          case 2:    n0 *= n1;            break;
  1814. X          case 3:    if(n0) n0=n1/n0; else fprintf(stderr,zero); break;
  1815. X          case 4:    if(n0) n0=n1%n0; else fprintf(stderr,zero); break;
  1816. X          case 5:    n0 &= n1;            break;
  1817. X          case 6:    n0 |= n1;            break;
  1818. X          case 7:    n0 =  ~n0    ;        break;
  1819. X          case 8:    n0 = (n1 > n0);        break;
  1820. X          case 9:    n0 = (n1 < n0);        break;
  1821. X          case 10:    n0 = (n0 == n1);    break;
  1822. X          case 11:    n0 = !n0;            break;
  1823. X          case 12:    n0=n1>n0 ? n1 : n0;    break;
  1824. X          case 13:    n0=n1<n0 ? n1 : n0;    break;
  1825. X          case 14:    n1=n0;                break;
  1826. X          case 15:    t=n0; n0=n1; n1=t;    break;
  1827. X          case 16:                        break;
  1828. X          case 17:    printf("In Commands Out\n");
  1829. X            for (temp=rpn; temp->str; temp++)
  1830. X                printf(" %d %-10s%d\n",
  1831. X                temp->parsin,temp->str,temp->parsout);
  1832. X            break;
  1833. X          default:    n0=Atol(av[i]);
  1834. X                if (IoErr()) {
  1835. X                    fprintf(stderr, "Bad RPN cmd: %s\n",av[i]);
  1836. X                    goto error;
  1837. X                }
  1838. X                break;
  1839. X          }
  1840. X        stack[sp]=n0;
  1841. X        stack[sp+1]=n1;
  1842. X        sp += rpn[j].parsout;
  1843. X    }
  1844. X    if( flag && sp-1) fprintf( stderr, "RPN: Stack not empty\n" );
  1845. X
  1846. Xexit:
  1847. X    t=sp; sp=oldsp;
  1848. X    if( flag )
  1849. X        return stack[t-1]; /* return top value */
  1850. X    else 
  1851. X        return t-sp;
  1852. X
  1853. Xerror:
  1854. X    sp=oldsp;
  1855. X    return 0;
  1856. X}
  1857. X
  1858. X
  1859. Xdo_rpn(char *garbage,int ifflag) /* ifflag!=0 if called from if */
  1860. X{
  1861. X    int i=1;
  1862. X    long t;
  1863. X
  1864. X    t=eval_rpn( av+i, ac-i, ifflag );
  1865. X    if (ifflag) return t;              /* called from if: return top value */
  1866. X    for (i=sp+t-1;i>=sp;i--) printf("%ld\n", stack[i]);/* else print stack */
  1867. X
  1868. X    return t ? 0 : 20;
  1869. X}
  1870. X
  1871. Xdo_path( void )
  1872. X{
  1873. X    ULONG ll, ll1, *lp, new, *newp;
  1874. X    char buf[256];
  1875. X    char buf2[256];
  1876. X    BPTR lock;
  1877. X    int i;
  1878. X
  1879. X    if( options&1 ) {
  1880. X        Forbid();
  1881. X        for( ll= Mycli->cli_CommandDir; ll; ll= ll1 ) {
  1882. X            lp=(ULONG *)(4*ll);
  1883. X            ll1=*lp;
  1884. X            DosFreeMem( lp );
  1885. X        }
  1886. X        Mycli->cli_CommandDir=0;
  1887. X        Permit();
  1888. X    } else if( ac==1 ) {     /* Should Forbid() here, but puts() Permit()s */
  1889. X        puts("Current dir"); /* and failure here is not really harmful...  */
  1890. X        for( ll= Mycli->cli_CommandDir; ll; ll= *lp ) {
  1891. X            lp=(ULONG *)(4*ll);
  1892. X            PathName(lp[1], buf, 256L);
  1893. X            puts(buf);
  1894. X        }
  1895. X        puts("C:");
  1896. X        return 0;
  1897. X    }
  1898. X    Forbid();
  1899. X    for( i=1; i<ac; i++ ) {
  1900. X        if( !(lock=Lock(av[i],ACCESS_READ)) ) {
  1901. X            pError(av[i]);
  1902. X            continue;
  1903. X        }
  1904. X        PathName(lock, buf, 256L);
  1905. X        for( ll= Mycli->cli_CommandDir, lp=NULL; ll; ll= *lp ) {
  1906. X            lp=(ULONG *)(4*ll);
  1907. X            PathName(lp[1],buf2,256L);
  1908. X            if( !Strcmp(buf,buf2) ) {
  1909. X                UnLock(lock);
  1910. X                break;
  1911. X            }
  1912. X        }
  1913. X        if( !ll ) {
  1914. X            newp=DosAllocMem( 8 );
  1915. X            newp[1]=lock;
  1916. X            new =(ULONG)newp/4;
  1917. X            if( lp )
  1918. X                *lp=new;
  1919. X            else
  1920. X                Mycli->cli_CommandDir=new;
  1921. X        }
  1922. X    }
  1923. X    Permit();
  1924. X    return 0;
  1925. X}
  1926. X
  1927. Xdo_pri( void )
  1928. X{
  1929. X    int t, pri;
  1930. X    struct Process *proc;
  1931. X
  1932. X    t=(int)(long)FindCLI(0L);
  1933. X    t=myatoi(av[1],0,t); if (atoierr) return 20;
  1934. X    pri=myatoi(av[2],-128,127); if (atoierr) return 20;
  1935. X    Forbid();
  1936. X    proc=(t==0 ? Myprocess : FindCLI((long)t));
  1937. X    if (proc==NULL) fprintf(stderr, "process not found\n");
  1938. X    else SetTaskPri((struct Task *)proc, (long)pri);
  1939. X    Permit();
  1940. X    return 0;
  1941. X}
  1942. X
  1943. Xdo_strleft( void )
  1944. X{
  1945. X    int n;
  1946. X
  1947. X    n=posatoi(av[3]); if (atoierr) return 20;
  1948. X    set_var_n(LEVEL_SET, av[1], av[2], n);
  1949. X    return 0;
  1950. X}
  1951. X
  1952. Xdo_strright( void )
  1953. X{
  1954. X    int n, len=strlen(av[2]);
  1955. X
  1956. X    n=posatoi(av[3]); if (atoierr) return 20;
  1957. X    if( n>len ) n=len;
  1958. X    set_var(LEVEL_SET, av[1], av[2]+len-n );
  1959. X    return 0;
  1960. X}
  1961. X
  1962. Xdo_strmid( void )
  1963. X{
  1964. X    int n1, n2=999999, len=strlen(av[2]);
  1965. X
  1966. X    n1=myatoi(av[3],1,999999)-1; if (atoierr) return 20;
  1967. X    if (n1>len) n1=len;
  1968. X    if (ac>4) {
  1969. X        n2=posatoi(av[4]); if (atoierr) return 20;
  1970. X    }
  1971. X    set_var_n(LEVEL_SET, av[1], av[2]+n1, n2);
  1972. X    return 0;
  1973. X}
  1974. X
  1975. Xdo_strlen( void )
  1976. X{
  1977. X    char buf[16];
  1978. X
  1979. X    sprintf(buf,"%d",strlen(av[2]));
  1980. X    set_var(LEVEL_SET, av[1], buf);
  1981. X    return 0;
  1982. X}
  1983. X
  1984. Xint atoierr;
  1985. X
  1986. Xmyatoi(s,min,max)
  1987. Xchar *s;
  1988. X{
  1989. X    int n;
  1990. X
  1991. X    n=Atol(s);
  1992. X    if (atoierr=IoErr())
  1993. X        ierror(s,511);
  1994. X    else if (n<min || n>max) {
  1995. X        atoierr=1; n=min;
  1996. X        fprintf( stderr, "%s(%d) not in (%d,%d)\n",s,n,min,max );
  1997. X    }
  1998. X    return n;
  1999. X}
  2000. X
  2001. Xunlatoi(char *s)
  2002. X{
  2003. X    int n=Atol(s);
  2004. X    if (atoierr=IoErr())
  2005. X        ierror(s,511), n=0;
  2006. X    return n;
  2007. X}
  2008. X
  2009. Xposatoi(char *s)
  2010. X{
  2011. X    int n=Atol(s);
  2012. X    if (atoierr=IoErr())
  2013. X        ierror(s,511);
  2014. X    else if (n<0 )
  2015. X        atoierr=1, n=0, fprintf( stderr, "%s must be positive\n",s );
  2016. X    return n;
  2017. X}
  2018. X
  2019. X
  2020. Xdo_fltlower( void )
  2021. X{
  2022. X    return line_filter( strlwr );
  2023. X}
  2024. X
  2025. Xdo_fltupper( void )
  2026. X{
  2027. X    return line_filter( strupr );
  2028. X}
  2029. X
  2030. X#if 0
  2031. Xchar *
  2032. Xstripcr( char *get )
  2033. X{
  2034. X    char *old=get, *put;
  2035. X
  2036. X    for( put=get; *get; get++ )
  2037. X        if( *get!=13 )
  2038. X            *put++=*get;
  2039. X    *put++=0;
  2040. X    return old;
  2041. X}
  2042. X
  2043. Xdo_fltstripcr( void )
  2044. X{
  2045. X    return line_filter( stripcr );
  2046. X}
  2047. X#endif
  2048. X
  2049. Xint
  2050. Xline_filter( char *(*func)( char * ) )
  2051. X{
  2052. X    char buf[256];
  2053. X
  2054. X    while (!CHECKBREAK() && gets(buf))
  2055. X        puts((*func)(buf));
  2056. X    return 0;
  2057. X}
  2058. X
  2059. Xdo_linecnt( void )
  2060. X{
  2061. X    int count=0;
  2062. X    char buf[256];
  2063. X
  2064. X    while (!CHECKBREAK() && gets(buf)) ++count;
  2065. X    printf("%d lines\n",count);
  2066. X    return 0;
  2067. X}
  2068. X
  2069. Xdo_uniq( void )
  2070. X{
  2071. X    int firstline=1;
  2072. X    char buf[256], oldbuf[256];
  2073. X
  2074. X    while (!CHECKBREAK() && gets(buf)) {
  2075. X        if ( firstline || strcmp(buf, oldbuf)) {
  2076. X            strcpy(oldbuf, buf);
  2077. X            puts(buf);
  2078. X        }
  2079. X        firstline=0;
  2080. X    }
  2081. X    return 0;
  2082. X}
  2083. X
  2084. X
  2085. X#define RXFB_RESULT  17
  2086. X
  2087. Xstatic struct rexxmsg {
  2088. X    struct Message cm_Node;
  2089. X    LONG   RFU1;
  2090. X    LONG   RFU2;
  2091. X    LONG   rm_Action;
  2092. X    LONG   rm_Result1;
  2093. X    LONG   rm_Result2;
  2094. X    char   *cm_Args[16];
  2095. X    LONG   RFU7;
  2096. X    LONG   RFU8;
  2097. X    LONG   RFU9;
  2098. X    LONG   RFU10;
  2099. X    LONG   RFU11;
  2100. X    LONG   RFU12;
  2101. X} mymsg;
  2102. X
  2103. Xdo_rxsend( char *avline )
  2104. X{
  2105. X    int i;
  2106. X    long result;
  2107. X    struct MsgPort *port, *reply;
  2108. X    long len;
  2109. X    char buf[20], *resptr;
  2110. X
  2111. X    if (!(port = FindPort(av[1])))
  2112. X        { fprintf(stderr, "No port %s!\n", av[1]); return 20; }
  2113. X    mymsg.cm_Node.mn_Node.ln_Type = NT_MESSAGE;
  2114. X    mymsg.cm_Node.mn_Length = sizeof(struct rexxmsg);
  2115. X    mymsg.rm_Action = (options&1 ? 1L << RXFB_RESULT : 0);
  2116. X    if (!(reply = CreatePort(NULL, 0L))) {
  2117. X        fprintf(stderr, "No reply port\n");
  2118. X        return 20;
  2119. X    }
  2120. X    mymsg.cm_Node.mn_ReplyPort = reply;
  2121. X
  2122. X    if( options&2 )
  2123. X        av[2]=compile_av( av,2,ac,' ',0), ac=3;
  2124. X    for ( i=2; i<ac; i++) {
  2125. X        mymsg.cm_Args[0] = av[i];
  2126. X        mymsg.rm_Result2 = 0;        /* clear out the last result. */
  2127. X        PutMsg(port, &mymsg.cm_Node);
  2128. X        WaitPort(reply);
  2129. X
  2130. X        if (options&1) {
  2131. X            if( (result=mymsg.rm_Result2)<1000000 ) { /* so does it AREXX */
  2132. X                sprintf(buf,"%d",result);              
  2133. X                set_var(LEVEL_SET,v_result,buf);
  2134. X            } else {
  2135. X                resptr=(char *)(result-4);
  2136. X                len=*(long *)resptr;
  2137. X                memmove(resptr,resptr+4,len);  /* Null terminate */
  2138. X                resptr[len]=0;      
  2139. X                set_var(LEVEL_SET,v_result,resptr);
  2140. X                FreeMem(resptr, len+4 );
  2141. X            }
  2142. X        } else 
  2143. X            unset_var( LEVEL_SET, v_result );
  2144. X    }
  2145. X    if( options&2 )
  2146. X        free( av[2] );
  2147. X
  2148. X    if (reply) DeletePort(reply);
  2149. X    return 0;
  2150. X}
  2151. X
  2152. Xstatic char *rxreturn;
  2153. X
  2154. Xdo_rxrec( void )
  2155. X{
  2156. X    struct MsgPort *port;
  2157. X    struct rexxmsg *msg;
  2158. X    char *portname, *str;
  2159. X
  2160. X    if (ac > 1)
  2161. X        portname=av[1];
  2162. X    else
  2163. X        portname="rexx_csh";
  2164. X
  2165. X    port=CreatePort(portname, 0L);
  2166. X    if (port==NULL) {
  2167. X        fprintf(stderr, "Can't have MsgPort %s\n", portname);
  2168. X        return 20;
  2169. X    }
  2170. X    for (;;) {
  2171. X        WaitPort(port);
  2172. X        while (msg=(struct rexxmsg *)GetMsg(port)) {
  2173. X            if ( ! Strcmp(msg->cm_Args[0], "bye")) {
  2174. X                ReplyMsg((struct Message *)msg);
  2175. X                DeletePort(port);
  2176. X                return 0;
  2177. X            }
  2178. X            rxreturn=NULL;
  2179. X            exec_command(msg->cm_Args[0]);
  2180. X            if (msg->rm_Action & (1L << RXFB_RESULT)) {
  2181. X                if( rxreturn ) {
  2182. X                    str= AllocMem( strlen( rxreturn )+5 , 0 );
  2183. X                    *(long *)str=strlen( rxreturn );
  2184. X                    strcpy( str+4, rxreturn );
  2185. X                    msg->rm_Result2=(long)str;
  2186. X                } else {
  2187. X                    str = get_var(LEVEL_SET, v_lasterr);
  2188. X                    msg->rm_Result2=(str) ? atoi(str) : 20;
  2189. X                }
  2190. X            }
  2191. X            ReplyMsg((struct Message *)msg);
  2192. X        }
  2193. X    }
  2194. X}
  2195. X
  2196. Xint
  2197. Xdo_waitport( void )
  2198. X{
  2199. X    int count=4*10;
  2200. X    struct MsgPort *port;
  2201. X
  2202. X    if( ac==3 ) 
  2203. X        { count=2*myatoi(av[2],0, 32000); if( atoierr ) return 20; }
  2204. X
  2205. X    while( --count>=0 && !(port=FindPort(av[1])) && !dobreak() )
  2206. X        Delay(12);
  2207. X
  2208. X    return port ? 0 : 20;
  2209. X}
  2210. X
  2211. Xint
  2212. Xdo_rxreturn( void )
  2213. X{
  2214. X    rxreturn=compile_av( av, 1, ac, ' ', 1 );
  2215. X    return 0;
  2216. X}
  2217. X
  2218. Xdo_ascii( void )
  2219. X{
  2220. X    int x=1, y, c, c1, t;
  2221. X    char *fmt1=" %3d %c%c |", *fmt2=" %4d";
  2222. X
  2223. X    if( options&1 ) fmt1=" %3o %c%c |", fmt2="%4o";
  2224. X    if( options&2 ) fmt1=" %3x %c%c |", fmt2="%4x";
  2225. X    if( ac==x )
  2226. X        for( y=0; y<32 && !dobreak(); y++ ) {
  2227. X            printf("|");
  2228. X            for( x=0; x<8; x++ ) {
  2229. X                c1=c=y+32*x; t=' ';
  2230. X                if( c<32 ) t='^', c1+=64;
  2231. X                printf(fmt1,c, t, c1<128 || c1>=160?c1:'.');
  2232. X            }
  2233. X            printf("\n");
  2234. X        }
  2235. X    else 
  2236. X        for( ; x<ac && !dobreak(); x++ ) {
  2237. X            for( y=0; y<strlen(av[x]); y++ )
  2238. X                printf(fmt2,av[x][y]);
  2239. X            printf("\n");
  2240. X        }
  2241. X    return 0;
  2242. X}
  2243. X
  2244. Xvoid
  2245. Xappendslash( char *path )
  2246. X{
  2247. X    int c;
  2248. X
  2249. X    if( (c=path[strlen(path)-1]) !='/' && c!=':' )
  2250. X        strcat(path,"/");
  2251. X}
  2252. X
  2253. Xstatic void
  2254. Xwhereis( char *path, char *file )
  2255. X{
  2256. X    char **eav, buf[100];
  2257. X    int  eac, j;
  2258. X
  2259. X    buf[0]=0;
  2260. X    if( path ) {
  2261. X        strcpy(buf,path);
  2262. X        appendslash(buf);
  2263. X    }
  2264. X    strcat(buf,".../");
  2265. X    strcat(buf,file);
  2266. X    if( !index( file, '*' ) && !index( file, '?') )
  2267. X        strcat(buf,"*");
  2268. X    if(eav=expand(buf,&eac)) {
  2269. X        for( j=0; j<eac && !dobreak(); j++ )
  2270. X            printf("%s\n",eav[j]);
  2271. X        free_expand(eav);
  2272. X    }
  2273. X}
  2274. X
  2275. Xdo_whereis( void )
  2276. X{
  2277. X    char buf[200], *prev, *devs;
  2278. X    int i;
  2279. X
  2280. X    if( index( av[1],':') || index( av[1],'/' ) )
  2281. X        { fprintf(stderr,"No paths please\n"); return 20; };
  2282. X
  2283. X    if( options&1 ) {
  2284. X        Myprocess->pr_WindowPtr = (APTR)(-1);
  2285. X        get_drives( devs=buf );
  2286. X        do {
  2287. X            prev=devs; devs=index(devs,0xA0);
  2288. X            if( devs ) *devs++=0; 
  2289. X            whereis( prev, av[1] );
  2290. X        } while( devs );
  2291. X        Myprocess->pr_WindowPtr = (APTR) o_noreq;
  2292. X    } else if( ac==2 ) {
  2293. X        whereis( NULL, av[1] );
  2294. X    } else {
  2295. X        for( i=2; i<ac; i++ ) {
  2296. X            strcpy(buf,av[i]);
  2297. X            appendslash( buf );
  2298. X            whereis( buf, av[1] );
  2299. X        }
  2300. X    }
  2301. X    return 0;
  2302. X}
  2303. X
  2304. Xdo_usage( void )
  2305. X{
  2306. X    int i;
  2307. X
  2308. X    if( ac==1 ) {
  2309. X        printf("Usage: usage [command...command]\n");
  2310. X        printf("[ ]=option   [ | ]=choice   { }=repetition   name...name=1 or more names\n");
  2311. X    } else 
  2312. X        for( i=1; i<ac; i++ )
  2313. X            show_usage( av[i] );
  2314. X    return 0;
  2315. X}
  2316. X
  2317. Xint NumMenus;
  2318. X
  2319. Xdo_menu( void )
  2320. X{
  2321. X    if( o_nowindow )
  2322. X        return 5;
  2323. X
  2324. X    if( options&1 )
  2325. X        remove_menu();
  2326. X
  2327. X    if( ac==2 )
  2328. X        show_usage( NULL );
  2329. X    else if( NumMenus<MAXMENUS && ac!=1)
  2330. X        install_menu( av+1, ac-1 );
  2331. X
  2332. X    set_menu();
  2333. X    return 0;
  2334. X}
  2335. X
  2336. X#define NUMITE 40
  2337. X#define TITWID 90
  2338. X#define ITEWID 148
  2339. X
  2340. Xstatic struct Menu DefaultMenu= {0, 0,0,TITWID,10, MENUENABLED,0,0};
  2341. Xstatic struct IntuiText DefaultIntuiText= {0,1,JAM2, 1,1,NULL,0,0};
  2342. Xstatic struct MenuItem DefaultMenuItem=
  2343. X  {0, 0,0,ITEWID,0, HIGHCOMP|ITEMTEXT|ITEMENABLED,0,0,0,0,0,0};
  2344. X
  2345. Xstruct Menu Menus[10];
  2346. Xchar *MenuCommand[MAXMENUS][MAXITEMS];
  2347. X
  2348. Xextern char *rindex();
  2349. X
  2350. Xstatic void
  2351. Xinstall_menu( char *mav[], int mac )
  2352. X{
  2353. X    struct TextAttr *ta;
  2354. X    struct Menu *m;
  2355. X    struct MenuItem *mi, **pmi;
  2356. X    struct IntuiText *it;
  2357. X    int y, i, fonthei;
  2358. X    char *p, *com;
  2359. X
  2360. X    if( o_nowindow || !Win )
  2361. X        return;
  2362. X
  2363. X    if( mac>=MAXITEMS )
  2364. X        mac=MAXITEMS-1;
  2365. X
  2366. X    ClearMenuStrip( Win );
  2367. X    Delay(3);
  2368. X
  2369. X    if( NumMenus )
  2370. X        Menus[NumMenus-1].NextMenu=Menus+NumMenus;
  2371. X    m  =&Menus[NumMenus];
  2372. X    *m =DefaultMenu;
  2373. X    m->LeftEdge  = NumMenus*TITWID;
  2374. X    m->MenuName  = strcpy(malloc(strlen(mav[0])+1),mav[0]);
  2375. X    if( strlen(m->MenuName)>TITWID/8 )
  2376. X        m->MenuName[TITWID/8+1]=0;
  2377. X    DefaultIntuiText.ITextFont=ta=Win->WScreen->Font;
  2378. X    DefaultMenuItem.Height=2+(fonthei=ta->ta_YSize);
  2379. X
  2380. X    y=0;
  2381. X    pmi=&m->FirstItem;
  2382. X    for( i=1; i<mac; i++) {
  2383. X        it =(void *)malloc(sizeof(struct IntuiText));
  2384. X        *it=DefaultIntuiText;
  2385. X        mi =(void *)malloc(sizeof(struct MenuItem ));
  2386. X        *mi=DefaultMenuItem;
  2387. X
  2388. X        com=NULL;
  2389. X        if( p=index(mav[i],',')) {
  2390. X            *p=0; com=++p;
  2391. X            if( p=index(com,',')) {
  2392. X                *p=0;
  2393. X                mi->Command=p[1];
  2394. X                mi->Flags |=COMMSEQ;
  2395. X            }
  2396. X        }
  2397. X
  2398. X        if( !com || !*com) {
  2399. X            com=strcpy(malloc(strlen(mav[i])+2),mav[i]);
  2400. X            MenuCommand[NumMenus][i-1]=com;
  2401. X            com+=strlen(com);
  2402. X            *com++=13;
  2403. X            *com=0;
  2404. X        } else {
  2405. X            MenuCommand[NumMenus][i-1]=strcpy(malloc(strlen(com)+1),com);
  2406. X        }
  2407. X
  2408. X        it->IText=(UBYTE *)strcpy(malloc(strlen(mav[i])+2),mav[i]);
  2409. X
  2410. X        *pmi= mi;
  2411. X        pmi = &mi->NextItem;
  2412. X        mi->TopEdge = y;
  2413. X        mi->ItemFill= (APTR)it;
  2414. X
  2415. X        y+=DefaultMenuItem.Height;
  2416. X    }
  2417. X
  2418. X    NumMenus++;
  2419. XMError:
  2420. X    return;
  2421. X}
  2422. X
  2423. X
  2424. Xvoid
  2425. Xremove_menu()
  2426. X{
  2427. X    if( NumMenus>0 ) {
  2428. X        struct MenuItem *mi, *nextmi;
  2429. X        int i,j;
  2430. X
  2431. X        for( i=0; i<NumMenus; i++ ) {
  2432. X            for( mi=Menus[i].FirstItem,j=0 ; mi; mi=nextmi,j++ ) {
  2433. X                free( ((struct IntuiText *)mi->ItemFill)->IText );
  2434. X                free( ((struct IntuiText *)mi->ItemFill) );
  2435. X                nextmi=mi->NextItem;
  2436. X                free(mi);
  2437. X                free(MenuCommand[i][j]);
  2438. X            }
  2439. X        }
  2440. X
  2441. X        NumMenus=0;
  2442. X        set_menu();
  2443. X    }
  2444. X}
  2445. X
  2446. X
  2447. Xvoid
  2448. Xset_menu()
  2449. X{
  2450. X    if( o_nowindow || !Win )
  2451. X        return;
  2452. X
  2453. X    if( NumMenus>0 )
  2454. X        SetMenuStrip( Win, Menus );
  2455. X    else 
  2456. X        ClearMenuStrip( Win );
  2457. X
  2458. X    Delay(3);
  2459. X}
  2460. X
  2461. Xdo_getenv( void )
  2462. X{
  2463. X    char buf[256], *val=buf, *getenv();
  2464. X
  2465. X    if( ac!=3 && ac!=2 ) {
  2466. X        show_usage( NULL );
  2467. X        return 20;
  2468. X    }
  2469. X    if( !Getenv(av[ac-1],buf,256))
  2470. X        val="";
  2471. X
  2472. X    if( ac==2 )
  2473. X        printf( "%s\n", val );
  2474. X    else 
  2475. X        set_var( LEVEL_SET, av[1], val );
  2476. X    return 0;
  2477. X}
  2478. X
  2479. X
  2480. Xdo_setenv( void )
  2481. X{
  2482. X    if( ac!=3 ) {
  2483. X        show_usage( NULL );
  2484. X        return 20;
  2485. X    } else {
  2486. X#ifndef AZTEC_C
  2487. X        char buf[300];
  2488. X        sprintf(buf, "%s=%s", av[1], av[2] );
  2489. X        putenv( buf );
  2490. X#else
  2491. X        setenv( av[1], av[2] );
  2492. X#endif
  2493. X    }
  2494. X    return 0;
  2495. X}
  2496. X
  2497. Xchar **
  2498. Xread_name( char *name, int *ac )
  2499. X{
  2500. X    FILE *file;
  2501. X    char **av=NULL;
  2502. X
  2503. X    *ac=0;
  2504. X    if( file=name ? fopen( name, "r") : stdin ) {
  2505. X        av=read_file( file, ac );
  2506. X        if( name ) fclose( file );
  2507. X    } else 
  2508. X        pError( name );
  2509. X    return av;
  2510. X}
  2511. X
  2512. X
  2513. Xchar **
  2514. Xread_file( FILE *file, int *ac )
  2515. X{
  2516. X    int buflen=4096, lines=0, i, offs;
  2517. X    char *buf, *ptr, *got, **lineptr;
  2518. X
  2519. X    if( !(buf=ptr=malloc( buflen )))
  2520. X        goto error;
  2521. X    do {
  2522. X        while( ptr+400 < buf+buflen && (got=fgets( ptr, 400, file ) ) &&
  2523. X               !dobreak()) {
  2524. X            ptr+=strlen(ptr)-1, lines++;
  2525. X            *ptr++=0;
  2526. X        }
  2527. X        if( ptr+256 < buf+buflen ) {
  2528. X            offs=ptr-buf;
  2529. X            if( !(buf=realloc( buf, buflen*=2 ) ) )
  2530. X                goto error;
  2531. X            ptr=buf+offs;
  2532. X        }
  2533. X    } while( got && !dobreak());
  2534. X    if( !(lineptr=(char **)malloc( (lines+1)*sizeof( char * ))))
  2535. X        goto error;
  2536. X    *lineptr++=buf;
  2537. X    for( ptr=buf, i=0; i<lines; i++ ) {
  2538. X        lineptr[i]=ptr;
  2539. X        ptr+=strlen(ptr)+1;
  2540. X    }
  2541. X    *ac=lines;
  2542. X    return lineptr;
  2543. X
  2544. Xerror:
  2545. X    if( buf ) free( buf );
  2546. X    fprintf( stderr, "Out of memory\n" );
  2547. X    *ac=0;
  2548. X    return NULL;
  2549. X}
  2550. X
  2551. Xvoid
  2552. Xfree_file( ptr )
  2553. X    char **ptr;
  2554. X{
  2555. X    if( ptr-- ) {
  2556. X        if( *ptr )
  2557. X            free( *ptr );
  2558. X        free(ptr);
  2559. X    }
  2560. X}
  2561. X
  2562. X
  2563. Xdo_qsort( void )
  2564. X{
  2565. X    char **lineptr;
  2566. X    int  lines, i;
  2567. X
  2568. X    if( ac==1 ) {
  2569. X        lineptr=read_file( stdin, &lines);
  2570. X        QuickSort( lineptr, lines );
  2571. X        prepscroll(0);
  2572. X        for( i=0; i<lines && !dobreak(); i++ ) {
  2573. X            quickscroll();
  2574. X            puts( lineptr[i] );
  2575. X        }
  2576. X        free_file( lineptr );
  2577. X    }
  2578. X    return 0;
  2579. X}
  2580. X
  2581. Xextern int w_width;
  2582. X
  2583. Xdo_truncate( void )
  2584. X{
  2585. X    char buf[256];
  2586. X    int  w=newwidth(), c;
  2587. X    char *ptr;
  2588. X
  2589. X    if( ac==2 )
  2590. X        w=atoi( av[1] );
  2591. X
  2592. X    prepscroll(0);
  2593. X    while( gets(buf) && !dobreak() ) {
  2594. X        for( c=0, ptr=buf; *ptr && c<w; ptr++ )
  2595. X            if( *ptr=='\t' )
  2596. X                c+=8-(c&7);
  2597. X            else if( *ptr==27 ) {
  2598. X                while( *ptr<'@' )
  2599. X                    ptr++;
  2600. X            } else 
  2601. X                c++;
  2602. X        *ptr=0;
  2603. X        quickscroll();
  2604. X        puts(buf);
  2605. X    }
  2606. X    return 0;
  2607. X}
  2608. X
  2609. Xint
  2610. Xdo_readfile( void )
  2611. X{
  2612. X    char **rav, *str=NULL;
  2613. X    int rac;
  2614. X
  2615. X    if( rav= read_name( ac>2 ? av[2] : NULL, &rac ) ) {
  2616. X        if( rac>255 ) rac=255;
  2617. X        if( str= compile_av( rav, 0, rac, 0xA0, 0 ) )
  2618. X            set_var( LEVEL_SET, av[1], str );
  2619. X        free_file( rav );
  2620. X    }
  2621. X    return str ? 0 : 20;
  2622. X}
  2623. X
  2624. Xint
  2625. Xdo_split( void )
  2626. X{
  2627. X    int i;
  2628. X    char *val, *gap, *oldval;
  2629. X
  2630. X    if( !(val=get_var( LEVEL_SET, av[1] )))
  2631. X        { fprintf( stderr, "%s undefined\n", av[0] ); return 20; }
  2632. X    oldval=val=strcpy(malloc(strlen(val)+1),val);
  2633. X    for( i=2; i<ac-1; i++ ) {
  2634. X        if( gap=index(val,0xA0 )) *gap=0;
  2635. X        set_var( LEVEL_SET, av[i], val );
  2636. X        val="";
  2637. X        if( gap ) *gap=0xA0, val=gap+1;
  2638. X    }
  2639. X    set_var( LEVEL_SET, av[ac-1], val );
  2640. X    free(oldval);
  2641. X    return 0;
  2642. X}
  2643. X
  2644. Xchar *
  2645. Xcopyof( char *str )
  2646. X{
  2647. X    return strcpy(malloc(strlen(str)+1),str);
  2648. X}
  2649. X
  2650. Xint
  2651. Xdo_class( char *avline )
  2652. X{
  2653. X    CLASS *new;
  2654. X
  2655. X    if( options&1 ) {
  2656. X        avline=next_word(avline);
  2657. X        for( new=CRoot,CRoot=NULL; new; new=new->next )
  2658. X            Free(new);
  2659. X    }
  2660. X
  2661. X    if( ac==1 ) {
  2662. X        for( new=CRoot; new; new=new->next )
  2663. X            printf("%s\n",new->name);
  2664. X        return 0;
  2665. X    }
  2666. X
  2667. X    avline=next_word(avline);
  2668. X    if(!(new=malloc( strlen(avline)+5)))
  2669. X        ierror( NULL, 512 );
  2670. X    else {
  2671. X        new->next=NULL;
  2672. X        strcpy( new->name,avline );
  2673. X        if( CRoot )
  2674. X            LastCRoot->next=new;
  2675. X        else 
  2676. X            CRoot=new;
  2677. X        LastCRoot=new;
  2678. X    }
  2679. X    return 0;
  2680. X}
  2681. X
  2682. Xdo_getcl( void )
  2683. X{
  2684. X    char *s=getclass(av[1]);
  2685. X    if( s ) printf("%s\n",s);
  2686. X    return 0;
  2687. X}
  2688. X
  2689. Xdo_action( char *argline )
  2690. X{
  2691. X    char *args, err;
  2692. X    int abort=options&1;
  2693. X
  2694. X    args=compile_av( av,3,ac,' ',0 );
  2695. X    err=doaction(av[2],av[1],args);
  2696. X    if( !abort )
  2697. X        if( err==10 )    fprintf(stderr,"Can't identify %s\n", av[2] );
  2698. X        else if(err==11) fprintf(stderr,"Can't '%s' this file\n",av[1] );
  2699. X    return abort ? !err : err;
  2700. X}
  2701. END_OF_FILE
  2702. if test 26877 -ne `wc -c <'comm3.c'`; then
  2703.     echo shar: \"'comm3.c'\" unpacked with wrong size!
  2704. fi
  2705. # end of 'comm3.c'
  2706. fi
  2707. echo shar: End of archive 3 \(of 6\).
  2708. cp /dev/null ark3isdone
  2709. MISSING=""
  2710. for I in 1 2 3 4 5 6 ; do
  2711.     if test ! -f ark${I}isdone ; then
  2712.     MISSING="${MISSING} ${I}"
  2713.     fi
  2714. done
  2715. if test "${MISSING}" = "" ; then
  2716.     echo You have unpacked all 6 archives.
  2717.     rm -f ark[1-9]isdone
  2718. else
  2719.     echo You still need to unpack the following archives:
  2720.     echo "        " ${MISSING}
  2721. fi
  2722. ##  End of shell archive.
  2723. exit 0
  2724. -- 
  2725. Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
  2726. Mail comments to the moderator at <amiga-request@uunet.uu.net>.
  2727. Post requests for sources, and general discussion to comp.sys.amiga.misc.
  2728.